I'm trying to get the count of a column in a table using a SQL query to a C# list
my sample code is below
"Select count(1) as Values, SM.Name from SM INNER JOIN Bill on SM.ID = Bill.AL INNER JOIN Details on Bill.ID = Details.ID"
I need to to add the count to a list<> Can some one tell me how to do that?
Since this count value doesn't have a column name I have given it the name "Values"
I have tried to get the value as following code
public IHttpActionResult Post(Brands brand)
{
DataTable dt = new DataTable();
List<Brands> list = new List<Brands>();
try
{
SqlConnection con =
new SqlConnection(
"MyConnectionString");
con.Open();
var query = "Select count(1) as Values, SM.Name from SM INNER JOIN Bill on SM.ID = Bill.AL INNER JOIN Details on Bill.ID = Details.ID";
SqlCommand com = new SqlCommand(query, con);
com.ExecuteNonQuery();
con.Close();
SqlDataAdapter adptr = new SqlDataAdapter(com);
adptr.Fill(dt);
for (int i = 0; i < dt.Rows.Count; i++)
{
Brands GetAll = new Brands();
GetAll.Count = Convert.ToInt32(dt.Rows[i]["Values"]);
GetAll.Name = dt.Rows[i]["Name"].ToString();
list.Add(GetAll);
}
}
catch (Exception e)
{
}
return Ok(list);
}
}
}
Thanks Every one for contributing to help me out. Special Thanks to #Kason. What I did was add Group by to SQL Query. That Solved the Issue. Hope this would be helpful to others.
I appriciate the efforsts and suggestion for all helpers,but some
comments are showing they have less knowledge of sql.
1)
you used column(1), please never ever use this syntax for
query,this is bad practice to get data,always use name of column.
2)
Someone posted that count(1) is equals to count() than it's
myth,because count() will provide count of all the rows where
count(1) will provide only count of that which are not null. (Not
believing try this in your system.)
keep this points in mind also
suggest to others,hope you like this post.
Related
I need to populate a datagrid with the following columns.
invnumber,itemname,rate,quantity..
itemname,rate,quantity comes from 1 table while invnumber comes from another table
I used to do like this
string commandText = "SELECT invnumber,cname,date FROM inv_table WHERE invnumber LIKE #id";
SqlCommand command = new SqlCommand(commandText, conn);
string searchParam = String.Format("%{0}%", text_inv.Text);
command.Parameters.AddWithValue("#id", searchParam);
using (SqlDataAdapter sda = new SqlDataAdapter(command))
{
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
dataGridView2.DataSource = dt;
}
}
Now i cannot directly assign the data source as 2 different tables are involved
dataGridView2.DataSource = dt;
How can i get around this.
To emit combined result from 2 or more different tables in a table, use either INNER JOIN, LEFT JOIN, RIGHT JOIN or UNION statement depending on your need.
In this case, you need to join first table and other table to get desired results, assume invnumber is unique or primary key. Here is an example:
string commandText = "SELECT other.invnumber, inv.cname, inv.date FROM inv_table AS inv
INNER JOIN other_table AS other
ON inv.invnumber = other.invnumber
WHERE other.invnumber LIKE #id";
Or if you have already defined classes for each table, use LINQ to SQL with lambda expression:
DataContext dc = new DataContext();
var results = dc.InvTable.Join(OtherTable, inv => inv.invnumber, other => other.invnumber, (inv, other) => new { invnumber = other.invnumber, cname = inv.cname, date = inv.date });
Any improvements and suggestions welcome.
Create a new class for the data structure of the 2 different table, populate the new one and use. (easier and the most clear solution)
I have three tables in my Access database
Part (tbl name)
PartNo
UnitPrice
Order(tbl name)
OrderNo
OrderLine (tbl name)
OrderNo
PartNo
Quantity
Basically I want to sum(Quantity by UnitPrice) of all the OrderLines where OrderLine.PartNo = Part.PartNo and OrderLine.OrderNo = Order.OrderNo and place the value in a column I created and added onto the data grid view so it creates a subtotal in the order table on the fly.
DataGridViewTextBoxColumn subtotalCol = new DataGridViewTextBoxColumn();
subtotalCol.Name = "SubtotalColumn";
subtotalCol.HeaderText = "Subtotal";
subtotalCol.ReadOnly = true;
dataGridViewPrevOrders.Columns.Add(subtotalCol);
This is where I am so far but I don't think I'm going about it the right way!
for (int i = 0; i < dataGridViewPrevOrders.RowCount - 1; i++)
{
connection.Open();
string orderNo = dataGridViewPrevOrders.Rows[i].Cells["OrderNo"].Value.ToString();
command.CommandText = "SELECT SUM(OL.Quantity * P.UnitPrice) FROM OrderLine OL INNER JOIN (SELECT * FROM [Part]) P ON OL.[PartNo] = P.[PartNo] WHERE [OrderNo] = #OrderNo";
command.Parameters.Add(new OleDbParameter("#orderNo", orderNo));
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
dataGridViewPrevOrders.Rows[i].Cells["SubtotalColumn"].Value = reader["Sub"].ToString();
}
connection.Close();
}
First: Please add the specific problem! Does it lead to an exception? What is the undesired behaviour? Please help us to help you.
On first sight I can only see that you have to correct your sql command to:
SELECT SUM(P.UnitPrice * OL.Quantity) AS sumOfOrder FROM Part AS P
INNER JOIN OrderLine AS OL ON P.[PartNo] = OL.[PartNo]
WHERE OL.[OrderNo] = #OrderNo;
Hint: Regarding your code, it seems to me that you must have an extra SQL-command somewhere to set the Orders to the dataGridViewPrevOrders. Then you want to execute an extra SQL command for every Order to calculate the sum. It would be better to query the sum of quantity and OrdersNo with one clever SQL SELECT commmand, where you combine these two Queries and set it in only one loop.
I am doing a standard exercise where displaying fields of three tables in a gridview but however have a syntax error in my inner join statement.
Any advice perhaps on where the syntax error lies.
try
{
conn = new OleDbConnection(#"Provider=Microsoft.Jet.OleDb.4.0;
Data Source =" + Server.MapPath("App_Data\\Shopping List.mdb"));
conn.Open();
DataSet ds = new DataSet();
OleDbDataAdapter dba = new OleDbDataAdapter(#"SELECT Ingredient.IngerdientId, Ingredient.IngredientName, Area.AreaName, Recipe.RecipeName, Ingredient.Quantity
FROM Ingredient
INNER JOIN Area ON Ingredient.AreaId = Area.AreaId
INNER JOIN Recipe ON Ingredient.RecipeId = Recipe.RecipeId", conn);
dba.Fill(ds);
gridIngredients.DataSource = ds;
gridIngredients.DataBind();
}
catch (Exception exe)
{
labMessage.Text = exe.Message;
}
The Access db engine requires parentheses when your FROM clause includes more than one join. I think this may do it, but you would be better off to build and test your SELECT statement within Access using its query designer if you can.
FROM (Ingredient
INNER JOIN Area ON Ingredient.AreaId = Area.AreaId)
INNER JOIN Recipe ON Ingredient.RecipeId = Recipe.RecipeId
I am using the following code :
EmpInfoDS = new DataSet();
con.Open(); // My connection name
string sqlRecords = "Select * FROM tbl_EmpInfo";
EmpInfoDA = new OleDbDataAdapter(sqlRecords, con);
EmpInfoDA.Fill(EmpInfoDS, "EmpInfo");
var sortedRows = (from myRow in EmpInfoDS.Tables["EmpInfo"].AsEnumerable()
orderby myRow["EmpID"] ascending
select myRow).ToArray();
EmpInfoDS.Tables.Remove("EmpInfo");
DataTable EmpInfo = sortedRows.CopyToDataTable();
EmpInfo.TableName = "EmpInfo";
EmpInfoDS.Tables.Add(EmpInfo);
con.Close();
to sort the values in a datatable. Then removing that datatable and filling the sorted rows into a datatable with the same name.
Can anyone tell me how much efficient this process is. ie. Performance drawbacks ???
If there's a better way to accomplish this; Please tell me.
Any help will be much appreciated. :)
Why don't you just order by in the database? That will always be way more efficient.
i.e.
EmpInfoDS = new DataSet();
con.Open(); // My connection name
string sqlRecords = "Select * FROM tbl_EmpInfo ORDER BY EmpID";
EmpInfoDA = new OleDbDataAdapter(sqlRecords, con);
EmpInfoDA.Fill(EmpInfoDS, "EmpInfo");
con.Close();
Always let the database do work that it's made to do. Sorting is a database function and not a C# function (when it comes to fetching data)
You can try
EmpInfoDS.Tables["EmpInfo"].Sort = "EmpID ASC";
DataTable EmpInfo = EmpInfoDS.Tables["EmpInfo"].DefaultView.ToTable();
EmpInfoDS.Tables.Add(EmpInfo);
//To remove sorting --- EmpInfoDS.Tables["EmpInfo"].Sort = string.Empty;
with this approach you may leave your old DataTable and change sorting expression
Here's my statement from my C# program:
(edit by gbn, formatted for clarity so not all on one line)
DbCommand.CommandText =
#"SELECT
HIST.MBRSEP, HIST.LOCATION, HIST.BILLTYPE, HIST.BILLMOYR, LOCINFO.CYCLE,
LOCINFO.DIST, LOCINFO.LOCATION
FROM
(CAV_MBRHISTDEL AS HIST INNER JOIN CAV_LOCINFODETL AS LOCINFO ON HIST.LOCATION = LOCINFO.LOCATION)
WHERE
LOCINFO.CYCLE = #CYCLE AND
LOCINFO.DIST = #DISTRICT AND
HIST.BILLTYPE = '09' AND
HIST.BILLMOYR <> '9999'";
Here's the error message:
ERROR [HY000] [Oracle][ODBC][Ora]ORA-00907: missing right parenthesis
There's only 2 parenthesis in my SQL statement, a right one and a left one. I'm not sure what the error is telling me. Any advice?
EDIT: Here is how the parameters are defined:
string cycle = cbCycle.Text;
string district = cbDistrict.Text.Substring(0,2);
And here is where I add them to the DbCommand:
DbCommand.Parameters.AddWithValue("#CYCLE", cycle);
DbCommand.Parameters.AddWithValue("#DISTRICT", district);
Here's my complete code that triggers when someone clicks the 'Go' button on my form:
private void btnGo_Click(object sender, EventArgs e)
{
//get parameters
string cycle = cbCycle.Text;
string district = cbDistrict.Text.Substring(0,2);
//create a connection to the database
OdbcConnection DbConnection = new OdbcConnection("DSN=UPN2;uid=xxx;pwd=xxxx");
DbConnection.Open();
//create a command to extract the required data and
//assign it to the connection string
OdbcCommand DbCommand = DbConnection.CreateCommand();
DbCommand.CommandText =
#"SELECT HIST.MBRSEP, HIST.LOCATION, HIST.BILLTYPE, HIST.BILLMOYR, LOCINFO.CYCLE, LOCINFO.DIST, LOCINFO.LOCATION FROM CAV_MBRHISTDEL AS HIST INNER JOIN CAV_LOCINFODETL AS LOCINFO ON HIST.LOCATION = LOCINFO.LOCATION WHERE LOCINFO.CYCLE = #CYCLE AND LOCINFO.DIST = #DISTRICT AND HIST.BILLTYPE = '09' AND HIST.BILLMOYR <> '9999'; ";
DbCommand.Parameters.AddWithValue("#CYCLE", cycle);
DbCommand.Parameters.AddWithValue("#DISTRICT", district);
//Create a DataAdapter to run the command and fill the datatable
OdbcDataAdapter da = new OdbcDataAdapter();
da.SelectCommand = DbCommand;
DataTable dt = new DataTable();
da.Fill(dt);
tbOutput.Text = PrintDataTable(dt);
DbCommand.Dispose();
DbConnection.Close();
}
the problem might be that you are using an oracle reserved word as a column name and as a param name - namely CYCLE...
doing so might result in strange and erratic behaviour of the DB!
see http://download.oracle.com/docs/cd/B19306_01/em.102/b40103/app_oracle_reserved_words.htm
Depending on your db provider you might want to use : instead of # for params.
Try removing the parentheses that you have: you don't need them.
You're missing the SELECT from the inner query. Try this:
...
FROM
(SELECT CAV_MBRHISTDEL AS HIST -- Added SELECT
INNER JOIN CAV_LOCINFODETL AS LOCINFO ON HIST.LOCATION = LOCINFO.LOCATION)
WHERE
...
You have:
FROM
(CAV_MBRHISTDEL ... -- Missing SELECT