How to get the average of a column in MySQL - c#

I'm trying to find a way to calculate the average of a column (as a double/float or decimal). I've found the AVG function in MySQL documentation but I can't get it to work. Currently I've got the following code:
public double GetRating(string username)
{
double average;
MySqlConnection databaseConnection = new MySqlConnection(connectionString);
string sumQuery = "select sum('rating') from " + username;
string countQuery = "SELECT COUNT(*) FROM " + username;
using (MySqlCommand sumCommand = new MySqlCommand(sumQuery, databaseConnection))
using (MySqlCommand countCommand = new MySqlCommand(countQuery, databaseConnection))
try
{
databaseConnection.Open();
double sum = (Double)sumCommand.ExecuteScalar();
double columnLength = (Double)countCommand.ExecuteScalar();
average = sum / columnLength;
return average;
}
finally
{
databaseConnection.Close();
}
return average;
}
Now for some reason this does not work. It returns "Unable to cast object of type 'System.Int64' to type 'System.Double'."
The stored data in the database is an int but i'm trying to cast them to double. Any suggestions or solutions? Once again; double/float or decimal are usable for me.

The built-in AVG function (an aggregate function) could be used like so:
select avg(rating) from table_name
Note that, like most aggregate functions, the average will exclude null values (the average of 1, 2, null is 1.5 instead of 1.0). Also, in MySQL the return datatype will be decimal if you're averaging decimal or integer columns so use the appropriate C# datatype.

A couple of things:
What is the data type of the rating column in the table? If it is an integer and not floating-point, please change the data type of sum accordingly to avoid the type-cast error.
As you already know, you may use avg() instead of sum() and then division by count(). Your SQL will look like:
select avg(rating) from table_name

Related

SQL Server - Error converting data type float to bigint

Can the datatype of a field be changed to bigint from float ??
Create a new column that's an integer:
ALTER TABLE tabl ADD newCol int;
Select the data from the old column into the new one:
UPDATE tabl SET newCol = CAST(TEL2 AS int) FROM tabl ;
P.S: I am using MS SQL Server
i try to us this in c# but it didn't get any result
string sqlCommand = "SELECT * FROM tabl WHERE CONCAT([TEL1], [TEL2],[TEL3], [TEL4],[TEL5], [TEL6],[TEL7], [TEL8],[TEL9]) LIKE '%" + txtBoxSearch.Text + "%'";
I store telephone numbers as float and try find it by the c# code and didn't get any result so im trying to convert the column or correct the c# code
Try using the STR() function:
SELECT STR(your_float_field, 25, 0)
This would return your float value as a string.
Note: This function pads on the left with spaces. If this is a problem, combine with LTRIM function:
SELECT LTRIM(STR(your_float_field, 25, 0))
No,because float contain decimals
And bigint contain only integer.
But bigint can be converted into
Float as float contain both part -integer and decimals.
If your float value contains .00 as the decimal value then it can be changed into bigint.
Thanks.
If you want more about datatype conversion.then please comment.
Thanks again.

Rounding a field's value in a SELECT statement

What I need to do is to round a field to 2 decimals, but not in the usual way. I have a dropdown that's always rounded to 2 decimals (CIT_NBR). However, in the database table, it's sometimes rounded to 1 decimal. So now I'm trying to create a SELECT statement based on this field, but my front end stores it as 2 decimals and my back end can be stored as either 1 or 2 decimals. Don't ask, it's complicated. :o)
So, what I want to do in "aircode" is something like:
SELECT * FROM VW_MOS_DPL_AccountValidation WHERE CUST_NUM = #CNum
AND Format(CIT_NBR, 2 decimals) = #CITNum
This way, it forces the data in the table to use 2 decimals, so it can be compared to my dropdown.
Here's my code block:
using (SqlConnection con2 = new SqlConnection(str2))
{
using (SqlCommand cmd2 = new SqlCommand(#"SELECT * FROM VW_MOS_DPL_AccountValidation WHERE CUST_NUM = #CNum AND CIT_NBR = #CITNum", con2))
{
con2.Open();
cmd2.Parameters.AddWithValue("#CNum", TBAccountNum.Text);
string ddlCITVal2 = ddlCIT.SelectedValue;
cmd2.Parameters.AddWithValue("#CITNum", ddlCITVal2);
using (SqlDataReader DT2 = cmd2.ExecuteReader())
{
// If the SQL returns any records, process the info
if (DT2.HasRows)
{
while (DT2.Read())
{
.
.
.
etc
How could I go about doing this?
Cast the varchar to a decimal
SELECT SUM(Cast(CitNum as decimal(8,2))) as CitNum FROM table
There is a more performant approach, but this is easiest to read and maintain unless it causes a real performance problem.
SELECT *
FROM VW_MOS_DPL_AccountValidation
WHERE CUST_NUM = #CNum
AND (CIT_NBR=#CITNUM OR CIT_NBR+'0'=#CITNUM)
Unless you really meant rounded to one decimal instead of the example you gave which is just truncating a trailing zero, in which case a different approach would need to be used.

Double precision error when getting data from SQL server

I'm trying to get an real number from an SQL view.
But after executing the query it will round the number from 6728873.3 to 6728873.5
Why is this happening and is there any way around this?
I have tried getting the data with a DataReader, Linq2SQL and ServiceStack.ORMLite but none of them work.
var lConnection = new SqlConnection(ConnectionString);
const string cmd = "SELECT [Origin],[X],[Y] FROM [SpiderDB61].[dbo].[View_Addresses_AddressNames]" +
" where Origin = 5 and X = -26262.5 and Y = 6728873.3";
var lSQLCommand = new SqlCommand(cmd, lConnection);
lConnection.Open();
SqlDataReader lReader = lSQLCommand.ExecuteReader();
object a;
object b;
object c;
while (lReader.Read())
{
a = lReader[0];
b = lReader[1];
c = lReader[2]; // <-- this will be 6728873.5, not 6728873.3
}
real is float(24), which gives you approximately 7 digits of precision. 6728873.3 is 8 digits. Basically, you are at the limit of what is reliable / precise for real. You should consider a different data type; perhaps float (which defaults to float(53)), perhaps decimal(x,y) - depending on whether this value is meant to be discreet or continuous.

Error converting from numeric data type to decimal

Well here is my problem i have a table that contains the following column:
asis_doc_minutos decimal(4,1)
If i insert the following number (1.5) with a simple insert query it inserts it! BUT
my SProcedure doesn't inserts the data. Here is my Sp:
ALTER procedure [dbo].[insertar_pla_asis_doc]
#fecha datetime,
#tema varchar(500),
#minutos decimal(2,2),
#cod_docente int,
#cod_materia varchar(25),
#cod_seccion int,
#cod_ciclo int,
#cod_escuela int
as
begin
insert into pla_asis_doc(asis_doc_fecha, asis_doc_tema,
asis_doc_fecha_realizo, asis_doc_cod_docente, asis_doc_cod_mat, asis_doc_seccion,
asis_doc_cod_ciclo,
asis_doc_cod_escuela, asis_doc_minutos)
values (#fecha, #tema, getdate(), #cod_docente, #cod_materia, #cod_seccion,
#cod_ciclo, #cod_escuela, #minutos);
end
I'm calling this Sp from C# and this is the way i do it:
int valor_devuelto = puente.insertar(fecha, txtTema.Text,
Convert.ToDecimal(lblHoras.Text), cod_emp, cod_materia, seccion,
Convert.ToInt32(ciclo.Text), cod_esc);
Notice that (lblHoras.Text) is called from a TextBox and so i convert it to Decimal becasue that's what my column expects. That lines calls to a method in another class, which is the one that calls my Sp in my db and where i got the error, here is that code:
public int insertar(DateTime fecha, string tema, decimal minutos, int docente, string materia_codigo, int seccion, int ciclo, int escuela_cod)
{
int valor = 0;
try
{
cn.Open();
cmd.Connection = cn;
cmd.CommandText = "insertar_pla_asis_doc";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("#fecha", System.Data.SqlDbType.DateTime).Value = fecha;
cmd.Parameters.Add("#tema", System.Data.SqlDbType.VarChar).Value = tema;
cmd.Parameters.Add("#minutos", System.Data.SqlDbType.Decimal).Value = minutos;
cmd.Parameters.Add("#cod_docente", System.Data.SqlDbType.Int).Value = docente;
cmd.Parameters.Add("#cod_materia", System.Data.SqlDbType.VarChar).Value =
materia_codigo;
cmd.Parameters.Add("#cod_seccion", System.Data.SqlDbType.Int).Value = seccion;
cmd.Parameters.Add("#cod_ciclo", System.Data.SqlDbType.Int).Value = ciclo;
cmd.Parameters.Add("#cod_escuela", System.Data.SqlDbType.Int).Value =
escuela_cod;
valor = cmd.ExecuteNonQuery();
cn.Close();
}
catch (Exception ex)
{
}
return valor;
}
Everytime i run this code there's an error saying:
Error al convertir el tipo de datos numeric a decimal. (Error converting ) How can i solve that?
Your parameter in the procedure is declared as
#minutos decimal(2,2)
It means two numbers, both right of decimal point.
Check this sample:
create table #t (d decimal(2,2))
insert #t values (1.5)
Increase the size of the parameter.
The answer from #dean above was not very accurate.
It will failed as #steve mentioned.
create table #t (d decimal(2,2))
insert #t values (1.5)
the result will be:
"Msg 8115, Level 16, State 8, Line 1
Arithmetic overflow error converting numeric to data type numeric.
The statement has been terminated."
Correction:
create table #t (d decimal(3,2))
insert #t values (1.5)
Please see explanation below:
Decimal and numeric arguments:
decimal[ (p[ , s] )] and numeric[ (p[ , s] )]
Fixed precision and scale numbers. When maximum precision is used, valid values are from - 10^38 +1 through 10^38 - 1. The ISO synonyms for decimal are dec and dec(p, s). numeric is functionally equivalent to decimal.
p (precision)
The maximum total number of decimal digits that will be stored, both to the left and to the right of the decimal point. The precision must be a value from 1 through the maximum precision of 38. The default precision is 18.
s (scale)
The number of decimal digits that will be stored to the right of the decimal point. This number is substracted from p to determine the maximum number of digits to the left of the decimal point. The maximum number of decimal digits that can be stored to the right of the decimal point. Scale must be a value from 0 through p. Scale can be specified only if precision is specified. The default scale is 0; therefore, 0 <= s <= p. Maximum storage sizes vary, based on the precision.

converting SQL double in String

I am getting a problem when fetching double value from using linq and converting it into string. My code is:-
public List<ShowDataOnClient> GetCardListToShow()
{
try
{
List<ShowDataOnClient> CardList = new List<ShowDataOnClient>();
using (ProgressCardLINQDataContext c = new ProgressCardLINQDataContext())
{
CardList = (from card in c.GetTable<T_PROGRESSCARD>()
where card.RecordStatus.Equals(RecordStatus.Active)
select new ShowDataOnClient
{
Student=(from student in c.T_STUDENTs
where student.Id.Equals(card.StudentId)
select student.Name).Single().ToString(),
Test=(from test in c.T_TESTs
where test.Id.Equals(card.TestId)
select test.Name).Single().ToString(),
MaxMarks = (from test in c.T_TESTs
where test.Id.Equals(card.TestId)
select test.MaxMarks).Single().ToString(),
MarksObtain=card.MarksObtain.ToString(),
Percentage=card.Percentage.ToString()
}).ToList<ShowDataOnClient>();
}
return CardList;
}
catch
{
return new List<ShowDataOnClient>();
}
}
I have tried this also:-
Percentage=Math.Truncate(card.Percentage).ToString()
and when i pass "N2" in ToString it gives exception "Method 'System.String ToString(System.String)' has no supported translation to SQL."
and the value i got after conversion is like this:- 5.200000000000000e+001
is there anybody to help me..
Your ShowDataOnClient class should store the value of Percentage as a double. You can format the way doubles are presented to the user at a later stage. How you do that depends on the control you're using to show the data.
This has the added benefit that sorting functions would work as expected. If you convert your percentage to string this early, sorting by that column won't look right
% as String % as double
1% 1%
10% 2%
11% 10%
2% 11%
23% 23%
etc. etc.
Try this:
double Percentage = card.Percentage;
string PercentageStr = Percentage.ToString();
This will not invoke linq to sql and give you what you want.

Categories