I have written this code to retrieve some information from two tables in database. But when I run it I get this error
Column 'Eaten_food.Cardserial' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Code:
private void button8_Click(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection(WF_AbsPres_Food.Properties.Settings.Default.DbConnectionString))
{
con.Open();
SqlDataAdapter a = new SqlDataAdapter("SELECT Eaten_food.Cardserial , Eaten_food.Date , Eaten_food.Turn , Avb_food_count , Reserve_count from Reserve inner join Eaten_food on Reserve.Cardserial = Eaten_food.Cardserial group by Eaten_food.Date", con);
SqlCommandBuilder comdBuilder = new SqlCommandBuilder(a);
DataTable t = new DataTable();
//t.Locale = System.Globalization.CultureInfo.InvariantCulture;
a.Fill(t);
bindingSource3.DataSource = t;
/// bind the grid view with binding source
Reserve_dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
Reserve_dataGridView.ReadOnly = true;
Reserve_dataGridView.DataSource = bindingSource3;
Reserve_dataGridView.DataSource = t;
con.Close();
}
}
How can I solve it?
The problem is your sql query. If you use Group By you cannot select columns that are not grouped by or that are not aggregated(f.e. by using Min/Max/Avg/Count).
So you could make it working for example in this way, change your old query here:
SELECT eaten_food.cardserial,
eaten_food.date,
eaten_food.turn,
avb_food_count,
reserve_count
FROM reserve
INNER JOIN eaten_food
ON reserve.cardserial = eaten_food.cardserial
GROUP BY eaten_food.date
to:
SELECT MIN(eaten_food.cardserial)AS Cardserial,
eaten_food.date,
MIN(eaten_food.turn) AS Turn,
SUM(avb_food_count) AS SumFoodCount,
SUM(reserve_count) AS SumReserveCount
FROM reserve
INNER JOIN eaten_food
ON reserve.cardserial = eaten_food.cardserial
GROUP BY eaten_food.date
You have a problem with you SQL statement itself. I would copy it to SQL management studio and debug it.
The group function is to create summary rows and because of that your select columns would either need to be part of the group by clause or a summary type of statmet like sum(x) or count(x)
The following might work..
SELECT Eaten_food.Cardserial ,
Eaten_food.Date ,
Count(Eaten_food.Turn) ,
sum(Avb_food_count) ,
sum(Reserve_count)
FROM Reserve
INNER JOIN Eaten_food ON Reserve.Cardserial = Eaten_food.Cardserial
GROUP BY Eaten_food.Date, Eaten_food.CardSerial
Related
I'm trying to build a query that can give me the different rows between two tables.
Here is my code:
try
{
string searchquery = "SELECT* FROM NewList EXCEPT SELECT* FROM Restaurants UNION All";
SqlCommand searchcom = new SqlCommand(searchquery, connection);
SqlDataAdapter da = new SqlDataAdapter(searchcom);
DataSet ds = new DataSet();
connection.Open();
da.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
connection.Close();
}
catch (Exception er)
{
Debug.WriteLine(er.Message);
return;
}
I get the following error:
Incorrect syntax near 'All'.
What is the correct way/syntax to use Union All in SqlCommand class? I've tried to put it it my query string in too many ways but it's giving me the same error every time. How can I implement it in my search query with correct syntax ?
Your query is incorrect from UNION ALL on.
You can try it like this:
string searchquery = "SELECT * FROM NewList UNION ALL SELECT * FROM Restaurants ";
However, you need to be aware that:
It does not remove duplicate rows between the various SELECT statements (all rows are returned)
Each SELECT statement within the UNION ALL must have the same number of columns in the result sets with similar data types
Read here for more details.
Updated
You should use EXCEPT instead of UNION ALL if you want to get rows in one table that are not present in the other one.
Select Checking.RestID, FROM
(SELECT RestID FROM NewList EXCEPT Select RestID from Restaurants) as Checking
LEFT JOIN NewList ON Checking.RestID = NewList.RestID
this worked, thanks to anyone !
I'm working on a project and I add a query on navicat that displayed the results I wanted perfectly but when I used that same query on my project it only showed 5 rows of results.
the code im using for filling the datagridview and fetching the data is the following.
string cs = "*info*";
MySqlConnection liga = new MySqlConnection(cs);
string query = "*I have the full query futher down, its big and it looks stange in here*";
MySqlCommand comando = new MySqlCommand(query, liga);
int nInt = Convert.ToInt32(textBox1.Text);
comando.Parameters.AddWithValue("#ni", nInt);
try
{
liga.Open();
MySqlDataReader leitor = comando.ExecuteReader();
DataTable tabela = new DataTable();
tabela.Load(leitor);
dataGridView1.DataSource = tabela;
leitor.Close();
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
liga.Close();
}
QUERY
SELECT
disciplinas.nome AS Disciplina,
mods_alunos.numero,
mods_alunos.nota
FROM
mods_alunos
INNER JOIN disciplinas ON mods_alunos.codDisc = disciplinas.codDisc
WHERE
nInterno = #ni
I've come to the conclusion that it has to do with the INNER JOIN because is i just do SELECT * FROM mods_alunos it displays more than 5 results
EDIT 1:
You should consider using an LEFT OUTER JOIN instead of INNER JOIN like
SELECT
disciplinas.nome AS Disciplina,
mods_alunos.numero,
mods_alunos.nota
FROM mods_alunos
LEFT OUTER JOIN disciplinas ON mods_alunos.codDisc = disciplinas.codDisc
WHERE nInterno = #ni
You have used ExecuteReader method which returns only 1 row at a time.
You can use ExecuteScalar method which returns a complete table which can be used to fill Gridview.
im having a problam to write my DB to my DataGridView .
i have 3 tables (my data bases) and im doing join on all of them by selected values as in my code below :
public void ByPeople(string idToSearch)
{
string constring = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\sam\Documents\Visual Studio 2015\Projects\roject\roject\DB.mdf;Integrated Security=True";
using (SqlConnection myconnection = new SqlConnection(constring))
{
using (SqlCommand sqlCommand = new SqlCommand("SELECT p.Id, p.FirstName, p.LastName , m.TagNumber, m.Date, m.Group, m.Location, r.Eye, r.Shallow, r.Deep FROM PeopleTable p JOIN MainTable m ON p.Id=m.Id JOIN ResultsTable r ON r.TagNumber=m.TagNumber AND r.Date= m.Date where m.Id=#Id", myconnection))
{
sqlCommand.Parameters.AddWithValue("#Id",idToSearch);
myconnection.Open();
SqlDataAdapter adap = new SqlDataAdapter(sqlCommand);
System.Data.DataTable dt = new System.Data.DataTable();
adap.Fill(dt);
dataGridView1.DataSource = dt;
}
}
}
and im getting an Error :
"Incorrect syntax near the keyword 'Group' "
and im not using any Group by or something like that , maybe its because i have a column named Group ?(m.Group in the selected values in my query) , if i deletes m.Group its working good .
and my second question - in my dataGridView i have already writen columns names of my own , and i want to insert the data from DB to specific columns in my dataGridView , how can i do it ? beacause if im doing it like in my code , it inserts the data with the names of the columns in the DB , and i dont want it like this , i want to insert the data to specific columns that i choose in the datagridview with the names that already there .
thanks!
Group is a reserved keyword in SQL. You need to put brackets around all reserved keywords.
Regarding your second question: You can alias the names of the columns by using the AS keyword
SELECT p.Id, p.FirstName AS MyColumnName, p.LastName , m.TagNumber, m.[Date]
, m.[Group], m.[Location], r.Eye, r.Shallow
, r.Deep
FROM PeopleTable p
JOIN MainTable m
ON p.Id=m.Id
JOIN ResultsTable r
ON r.TagNumber=m.TagNumber
AND r.Date= m.Date
WHERE m.Id=#Id
I'm creating a small c# application linked to an online MySql database to further my knowledge on these 2 things.
In my database I have 2 tables "user" and "dvd" and they are build as this:
user: ID, GEBRUIKERSNAAM, PASWOORD
dvd: ID, TITLE,DUUR,USERID,...
What I'm trying to do now is take a colum from each table and display them in a dataGridView.
The colum's that I want are from table dvd: TITEL and from table user: GEBRUIKERSNAAM.
A dvd is linked to a user (One user many dvd's), using the ID from table user and the foreign key USERID from table dvd.
As a result I want to show 2 colums in my dataGridView one for the dvd's titel and the other kekst to the first for the owner of the dvd (witch is the GEBRUIKRSNAAM colum).
To do this I wrote the following code:
SELECT 'TITEL', dvd.TITEL
FROM xxx.dvd
UNION ALL
SELECT 'GEBRUIKERSNAAM', user.GEBRUIKERSNAAM
FROM xxx.user
INNER JOIN xxx.dvd ON user.ID = dvd.USERID
WHERE user.ID = xxx.dvd.USERID;
This however gives me 2 problems:
If I use it directly on my database (using the SQL tab from
phpMyAdmin) it works, but merges the 2 colums into one what I don't want. I think the problem here is the "Union All" piece, but I don't know how else to do this.
If I try to use this code using my c# application I get the following error: "Functionality SelectCommand.Connection is not initialized". I know the problem is somewere in this query because if I try it with a different query my code works like it is supposed to. (It fills the dataGridView).
try
{
MySqlCommand SelectCommand = new MySqlCommand("SELECT TITEL FROM xxx.dvd UNION ALL SELECT GEBRUIKERSNAAM FROM xxx.user INNER JOIN xxx.dvd ON user.ID = dvd.USERID WHERE user.ID = xxx.dvd.USERID;");
myConn.Open();
MySqlDataAdapter sda = new MySqlDataAdapter();
sda.SelectCommand = SelectCommand;
DataTable dbdataset = new DataTable();
sda.Fill(dbdataset);
BindingSource bSource = new BindingSource();
bSource.DataSource = dbdataset;
dataGridView1.DataSource = bSource;
sda.Update(dbdataset);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
myConn.Close();
Any help,tips or correct ways of doing something (best practice) on this problem are welcome
Thanks
I'm not totally clear on what your goal is, but maybe some part of this will help you:
SELECT U.GEBRUIKERSNAAM, D.TITLE
FROM dvd D JOIN user U ON D.USERID = U.ID
WHERE D.ID = 1
This will take the dvd table, and for each entry look up the user whose ID matches D.USERID. From that merged row, it will select the U.GEBRUIKERSNAAM and D.TITLE, but only results where the dvd ID is 1.
Please comment if there are further questions. I hope I understood your goal correctly. It may be easier if you gave me an example of what your desired output should look like & have me write the query.
If I understand your problem correctly then you need to display 2 columns where you to show wht user has hired the DVD for that you should use the query:
select d.TITLE, u.GEBRUIKERSNAAM
from dvd d
Inner join user u
ON u.ID = d.USERID
I tried to add a new row to a Table in an SQL DB, but I had a problem :
dynamic sql generation is not supported against multiple base tables
this is the code I tried :
private MyClass myClass = new MyClass();
private SqlDataAdapter adapter;
private SqlDataAdapter adapter2;
private void GestionCollections_Load(object sender, EventArgs e)
{
adapter = new SqlDataAdapter("select Id_Collection ID, Libelle_Collection Collection,Libelle_Editeur Editeur from Collection_ left join Editeur on Id_Editeur = Collection_.Id_Editeur_Editeur", myClass.cnx);
adapter.Fill(myClass.ds, "Collection_");
adapter2 = new SqlDataAdapter("Select Id_Editeur ID,Libelle_Editeur Editeur from Editeur", myClass.cnx);
adapter2.Fill(myClass.ds, "Editeur");
}
private void AjouterBarButton_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
String newKeyWordCollectionName = ajoutCollection.KeyWordCollectionName;
String newKeyWordAEditeurName = ajoutCollection.KeyWordEditeurName;
DataRow row = myClass.ds.Tables["Collection_"].NewRow();
row[1] = newKeyWordCollectionName;
foreach(var myRow in myClass.ds.Tables["Editeur"].AsEnumerable())
{
if (newKeyWordAEditeurName == myRow[1] as String)
row[2] = (int)myRow[0];
}
myClass.ds.Tables["Collection_"].Rows.Add(row);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.Update(myClass.ds, "Collection_");
}
Change your select query and add distinct with inner join.
For example there are two query from which you can understand that what I want to tell you
Wrong query
select iop.pob_id, iop.pob_product_id, iop.pob_qty, iop.pob_unit_id
, iop.pob_rate, iop.pob_value, iop.pob_fiscalyear_id
, **p.product_desc** as orderBy from inv_product_open_balc iop
left join inv_product p on iop.pob_product_id = p.product_id
where p.product_desc like 'Air Freshner%' and iop.pob_fiscalyear_id = 3
Correct query
select distinct iop.pob_id, iop.pob_product_id, iop.pob_qty
, iop.pob_unit_id, iop.pob_rate, iop.pob_value, iop.pob_fiscalyear_id
, **(select Product_desc from** inv_product p where p.product_id = iop.pob_product_id )as orderBy
from inv_product_open_balc iop
inner join inv_product p on iop.pob_product_id = p.product_id
where p.product_desc like 'Air Freshner%' and iop.pob_fiscalyear_id = 3
You can't use an SqlCommandBuilder here:
Automatically generates single-table commands that are used to reconcile changes made to a DataSet with...
The key words here being "single-table". It has no way to reverse engineer from the SELECT statement how a specific update should be applied (e.g. if you NULL all of the columns from the right side of a left join, should it delete the row, or set each column to null.
You need to author appropriate Insert, Update and Delete commands on the SqlDataAdapter.
With SqlCommandBuilder you can generate CRUD operation on entity
Requirement of use is to define Select command before inserting , and include in the select command your primary Key.
Link : http://msdn.microsoft.com/fr-fr/library/system.data.sqlclient.sqlcommandbuilder(v=vs.80).aspx
MSDN Definition : Automatically generate Transact-SQL statements to update single table
Nota : In your Update selectCommand, you defined left join query, and so you can create left join query, replace this query with just select.
Add DISTINCT in your select statement with inner join.
This will solve the issue.
like Select Distinct Employee.Ecode, .........