add column to existing query with GROUP BY - c#

I have got little issue, I'm trying to put another column klisluz.cena to existing query but its giving me errors that: Column klisluz.cena in command SELECT isnt correct, because its not in GROUP BY, but when I insert it in GROUP BY it throws the same error. Where should I put it ?
Thanks in advance. this is the query:
string sQuery = string.Format("SELECT zajsluz.akce,zajsluz.text,klisluz.pocet,klisluz.cena,klisluz.subkey,zajsluz.ID FROM zajsluz LEFT JOIN klisluz ON zajsluz.ID=klisluz.IDzajsluz WHERE zajsluz.akce= '{0}' and ISNULL(klisluz.subkey, '" + vyberradek + "') = '" + vyberradek + "' GROUP BY klisluz.subkey,zajsluz.akce,zajsluz.text,klisluz.pocet,zajsluz.ID", sZakce);

If your column "cena" is a numeric price value, then you could perform an Aggregate Function on it.
You could try to use the MAX(klisluz.cena) to get the maximum value, or SUM(..) to get a sum any other one that could apply to this column type.
http://msdn.microsoft.com/en-us/library/ms173454.aspx

klisluz.cena is not in the group by.

Related

Simple query for getting max value for each entity

Developing an application in C# using a MySQL database. It involves cows and their weights. When displaying the cows details in a table, I want to display all of the animal's details as well as their last weight.
I have two tables used for this: 'Cattle' and 'Weights'. Each animal has a unique ID and this ID is used as foreign key in weights table along with the date taken and what they weighed. Up to now the way I am doing it is getting the MAX(Date) in the weights table and using a left join however if animal wasn't weighed on that date then it won't be included. I could use each animals MAX(Weight) however some animals may drop in weight due to illness etc.
SELECT Cattle.TagNumber,
Cattle.HerdNumber,
Cattle.Breed,
Cattle.DOB,
Cattle.Group,
Weights.Weight
FROM Cattle
LEFT JOIN Weights ON Cattle.TagNumber = Weights.TagNumber
WHERE Cattle.Group = '" + group + "'
AND Date = '" + date.ToString("yyyy/MM/dd") + "'";
The above query is what I use when filtering the data by the animals group. I understand that I could go through each animal individually and get their MAX(Weight) however this severely hinders the performance.
If you select for the Max(Date) found on the join, instead of searching a specific Date (Where clause), you will always get the results. Not exactly sure if this is what is asked.
SELECT Cattle.TagNumber,
Cattle.HerdNumber,
Cattle.Breed,
Cattle.DOB,
Cattle.Group,
Weights.Weight,
MAX(Date)
FROM Cattle
LEFT JOIN Weights ON Cattle.TagNumber = Weights.TagNumber
WHERE Cattle.Group = '" + group + "'
Group by Cattle.TagNumber;
Edit
The query should also return values with no weights; you just need to filter the data. You can use Case (it might not work exactly as I wrote it, but something around that). There was the End missing; also you probably need to convert weight to a nvarchar (or what you chose), otherwise you will get an error when inserting weight in the column NAMECOLUMN
SELECT Cattle.TagNumber,
Cattle.HerdNumber,
Cattle.Breed,
Cattle.DOB,
Cattle.Group,
(Case when Weights.Weight is null then 'N/A' Else Convert(nvarchar(max),Weights.Weight) End) as NAMECOLUMN,
MAX(Date)
FROM Cattle
LEFT JOIN Weights ON Cattle.TagNumber = Weights.TagNumber
WHERE Cattle.Group = '" + group + "'
Group by Cattle.TagNumber;

SQL statement that only fetches the newest department which has been allocated

In my database i have the following rows and columns: https://i.imgur.com/ktUZY9d.jpg
My problem is the same employee has 3 different departments, but he is currently only active in 1. How do I change this SQL statement to only include the latest department he is in, which started in 2018 and ends in 2100, as seen by the ALLOCATION_START and ALLOCATION_END?
Query
string agentIdSubQuery = "SELECT DISTINCT " +
"AGENT_ID " +
"FROM " +
"KS_DRIFT.V_AGENT_ALLOCATION " +
"WHERE " +
"LENGTH(AGENT_INITIALS) < 5";
if(queryParams.SnapshotDate.HasValue)
agentIdSubQuery += " AND " + OracleConversion.ToOracleDate(queryParams.SnapshotDate) + " BETWEEN ALLOCATION_START AND ALLOCATION_END";
Update:
Tried alot of different solutions, but it crashes everytime, when i run through the debugger, further Down in this method this Query is causing me to crash:
string sql = "SELECT " +
"age1.* " +
"FROM " +
"KS_DRIFT.V_AGENT_ALLOCATION age1 " +
"INNER JOIN " +
"(" + agentIdSubQuery + ") age2 ON age1.AGENT_ID = age2.AGENT_ID " +
"ORDER BY " +
"AGENT_INITIALS";
Error Message:
{"Error occured during execution of SQL query: SELECT age1.* FROM KS_DRIFT.V_AGENT_ALLOCATION age1 INNER JOIN (SELECT max(DISTINCT AGENT_ID FROM KS_DRIFT.V_AGENT_ALLOCATION WHERE LENGTH(AGENT_INITIALS) < 5 AND '2018-08-15' BETWEEN ALLOCATION_START AND ALLOCATION_END AND (UPPER(AGENT_INITIALS) = 'JKKA')) age2 ON age1.AGENT_ID = age2.AGENT_ID ORDER BY AGENT_INITIALS."}
Also giving me an inner exception:
{"ORA-00904: \"AGE2\".\"AGENT_ID\": ugyldig identifikator"}
Debugging error screeenshot
Order it by the newest start date (descending) and select Top 1!
string agentIdSubQuery = "AGENT_ID " +
"FROM " +
"KS_DRIFT.V_AGENT_ALLOCATION " +
"WHERE " +
"LENGTH(AGENT_INITIALS) < 5 " +
" AND ROWNUM = 1 " +
" ORDER BY ALLOCATION_START DESC";
EDIT, changed Top 1 to Rownum = 1, for Oracle syntax
The table V_AGENT_ALLOCATION contains various departments per agent along with the dates the agent worked there. You want an agent's last department, which you get with Oracle's KEEP LAST. You haven't given us much information on your table, though. Let's say that the department is referenced by an allocation_id:
select
agent_id,
max(id_allocation) keep (dense_rank last order by allocation_start)
as id_current_allocation
from v_agent_allocation
group by agent_id
order by agent_id;
Your error message shows the final generated SQL:
{"Error occurred during execution of SQL query: SELECT age1.* FROM KS_DRIFT.V_AGENT_ALLOCATION age1 INNER JOIN (SELECT max(DISTINCT AGENT_ID FROM KS_DRIFT.V_AGENT_ALLOCATION WHERE LENGTH(AGENT_INITIALS) < 5 AND '2018-08-15' BETWEEN ALLOCATION_START AND ALLOCATION_END AND (UPPER(AGENT_INITIALS) = 'JKKA')) age2 ON age1.AGENT_ID = age2.AGENT_ID ORDER BY AGENT_INITIALS."}
If you format that so that it's readable, you get:
select age1.*
from ks_drift.v_agent_allocation age1
inner join
( select max(distinct agent_id
from ks_drift.v_agent_allocation
where length(agent_initials) < 5
and '2018-08-15' between allocation_start and allocation_end
and (upper(agent_initials) = 'JKKA') ) age2
on age1.agent_id = age2.agent_id
order by agent_initials
Two syntax issues should jump out:
There is a missing closing bracket after max(distinct agent_id (the distinct is also redundant)
The date literal is missing its date keyword - it should be date '2018-08-15' (or better still, a bind variable).
The brackets around (upper(agent_initials) = 'JKKA') are redundant but perhaps they arise from your generator logic and it's easiest to keep them.
I'm not sure how that relates to your 'newest allocated department' requirement, though. Some sample data (not a screenshot) would help.
If you're looking for the current department, you should compare the allocation dates with the current date.
Your query already has this WHERE clause, so it should work just fine for the example provided. But if you might want to specify that you need only ONE row using the ROWNUM special variable clause (assuming it's Oracle).
SELECT DISTINCT AGENT_ID
FROM KS_DRIFT.V_AGENT_ALLOCATION
WHERE LENGTH(AGENT_INITIALS) < 5
AND ALLOCATION_START < CURRENT_DATE AND CURRENT_DATE < ALLOCATION_END
AND ROWNUM = 1

mysql query to match some record where column contains multiple comma separated values

I am working on a project.I have a table tblhomework which have a column students code-which contains students code separated by comma.Now I have few drop downs to search a record among which is search by student name.Now I have students code in my table how should I match it against the student name.I am using the following query,till now I am matching using students code but now I have to match by student name
Query
string studentcode = "%" + txt_studentcode.Text.ToString() + "%";
SELECT
tblhomework.ID,
tblteacher.TEACHERNAME,
tblclass.CLASSNAME,
tblhomework.Title,
tblhomework.HomeworkDetail,
tblhomework.StudentsCode
FROM tblhomework
join tblclass on tblclass.CLASSCODE=tblhomework.ClassCode
join tblteacher on tblteacher.TSHORTNAME=tblhomework.Tshortcode
where tblhomework.StudentsCode like'" + studentcode + "';
Following is the screenshot of the result I am getting
I have a student table which contains student names of students which you can use.
Using FIND_IN_SET in your current SQL:-
SELECT
tblhomework.ID,
tblteacher.TEACHERNAME,
tblclass.CLASSNAME,
tblhomework.Title,
tblhomework.HomeworkDetail,
tblhomework.StudentsCode
FROM tblhomework
JOIN tblclass ON tblclass.CLASSCODE=tblhomework.ClassCode
JOIN tblteacher ON tblteacher.TSHORTNAME=tblhomework.Tshortcode
WHERE FIND_IN_SET('" + studentcode + "', tblhomework.StudentsCode);
However, not this will only work if there are no spaces before / after the commas in the list of student codes
To join that against the student names table (and making assumptions on the layout of that table) use something like this:-
SELECT
tblhomework.ID,
tblteacher.TEACHERNAME,
tblclass.CLASSNAME,
tblhomework.Title,
tblhomework.HomeworkDetail,
tblhomework.StudentsCode ,
tblstudent.StudentsName
FROM tblstudent
JOIN tblhomework ON FIND_IN_SET(tblstudent.StudentsCode, tblhomework.StudentsCode);
JOIN tblclass ON tblclass.CLASSCODE=tblhomework.ClassCode
JOIN tblteacher ON tblteacher.TSHORTNAME=tblhomework.Tshortcode
WHERE tblstudent.StudentsCode = '" + studentcode + "'
Searching by student name (although generally it would be easier if the drop down returned the numeric unique student id):-
SELECT
tblhomework.ID,
tblteacher.TEACHERNAME,
tblclass.CLASSNAME,
tblhomework.Title,
tblhomework.HomeworkDetail,
tblhomework.StudentsCode ,
tblstudent.StudentsName
FROM tblstudent
JOIN tblhomework ON FIND_IN_SET(tblstudent.StudentsCode, tblhomework.StudentsCode);
JOIN tblclass ON tblclass.CLASSCODE=tblhomework.ClassCode
JOIN tblteacher ON tblteacher.TSHORTNAME=tblhomework.Tshortcode
WHERE tblstudent.StudentsName = '" + studentname + "'
You can use 'FIND_IN_SET' function to search in comma separated set of values.
Change your where clause as below:
where FIND_IN_SET( #student_code, tblhomework.studentscode );
Use AddWithValue to bind value of 'studentcode' read from text box.
string studentcode = txt_studentcode.Text.ToString();
myCommand = new MySqlCommand( sql_query_string, connection );
myCommand.Parameters.AddWithValue( "#student_code", studentcode );
And execute.
To store comma separated values in column is bad design you should look at Database Normalization and do normalize your structure by storing all related student codes in a junction table,but as from above comments you said you can't change structure so in mysql you can use FIND_IN_SET() and join your students table ,i am not familiar with c# syntax so i have posted mysql query,also use your original name convention for the columns
SELECT
DISTINCT
h.ID,
t.TEACHERNAME,
c.CLASSNAME,
h.Title,
h.HomeworkDetail,
h.StudentsCode
FROM
tblhomework h
JOIN tblclass c
ON c.CLASSCODE = h.ClassCode
JOIN tblteacher t
ON t.TSHORTNAME = h.Tshortcode
JOIN students s ON(FIND_IN_SET(s.StudentsCode, h.StudentsCode) > 0)
WHERE FIND_IN_SET('studentcode', h.StudentsCode) > 0
OR s.student_name LIKE 'test'

MySQL Error: Column 'accountStatus' in field list is ambiguous

I have this piece of code here and i have the ambiguous error
if (Database.Query(ref reader, "SELECT fromID, toID, status, accountStatus, name FROM friends LEFT JOIN phpbb_users ON ( (user_id = toID) OR (user_id = fromID) ) AND (user_id != " + userID + ") WHERE (fromID=" + userID + " OR toID=" + userID + ")") == false)
{
return null;
}
Any help?
The optimizer is confused on what table accountStatus will it come from since both table contains column name accountStatus. To remove ambiguity error, add a table name before the column name in your SELECT clause.
Either
friends.accountStatus
or
phpbb_users.accountStatus
Specify the table name before column name
table.accountstatus
The ambigous message is probably telling you that your 'accountStatus' column exists in more than one table you are selecting from, so it doesn't know which table to select out of. Prefix the column names in your select list with the table names.
Both tables contains a column with the same name. You should help the parser to identify which table column you want. A simple way is using an alias
"SELECT f.fromID, f.toID, f.status, u.accountStatus, u.name " +
"FROM friends f LEFT JOIN phpbb_users u ON .......

SQL Returning rows with max value in column, within a specific range

I'm populating a DataTable in C# using an OleDbDataAdapter, and I am trying to get a query to work without much success.
The communication to/from the server works fine, as is evidenced by the simple query that returns all the records without any filter:
var commandText = string.Format("SELECT IsoShtRevID, LineID, Filename, Revision " +
"FROM dbo.PDSIsometricSheets WHERE SchemaName='{0}'", projectNo);
This gives me a list of about 8000 entries, however there is some redundancy.
There are multiple rows with the same LineID, but each one has a separate Revision value. I'm trying to get only the rows with the highest revision for each LineID, from a range of 0 to 5.
Here are a few of the attempts I've tried so far:
var commandText = string.Format("SELECT * FROM
(SELECT max(Revision) as LatestRev
FROM dbo.PDSIsometricSheets)
WHERE Revision < 5" , projectNo);
var commandText = string.Format("SELECT T.IsoShtRevID, T.LineID, T.Filename, T.Revision
FROM dbo.PDSIsometricSheets T
WHERE Revision =
(SELECT MAX(T1.Revision)
FROM dbo.PDSIsometricSheets T1
WHERE T1.IsoShtRevID = T.IsoShtRevID
)", projectNo);
var commandText = string.Format("SELECT IsoShtRevID, LineID, Filename, MAX(Revision) as LatestRevision
FROM dbo.PDSIsometricSheets WHERE SchemaName='{0}'
GROUP BY LineID, IsoShtRevID, Filename", projectNo);
Here are the questions I've visited so far trying to get this to work:
SQL Select only rows with Max Value on a Column
How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?
Fetch the row which has the Max value for a column
Select Rows with Maximum Column Value group by Another Column
Everything above either returns the same thing as my original query, or just errors out from bad syntax. SQL is the furthest thing from my forte, and I'm trying to figure out if I'm limited in functionality by using a DataAdapter.
UPDATE:
Here's the latest iteration, using some advice from below:
var commandText = string.Format("SELECT IsoShtRevID, LineID, Filename, MAX(Revision) as MaxRevision " +
"FROM dbo.PDSIsometricSheets " +
"WHERE SchemaName='{0}' AND Revision <= 5 AND Revision >= 0" +
"GROUP BY IsoShtRevID, LineID, Filename", projectNo);
This filters out the revision to values between 0 and 5, however there are still multiple rows for LineID, each with different Revision numbers. It's like the Max command is being ignored...
Option 3 should work but if it doesn't is because FileName or IsoShtRevID change across Revisions. In that case, you can do this:
SELECT a.IsoShtRevID ,
a.LineID ,
a.Filename ,
a.Revision
FROM dbo.PDSIsometricSheets a
join (select max(Revision) as Revision, LineID
from dbo.PDSIsometricSheets where SchemaName ='{0}' ) x
join a on a.Revision = x.Revision and a.LineID=x.LineID
WHERE a.SchemaName = '{0}'
Finally got it thanks to the comments, reading more SQL, and viewing my commandstring diligently at runtime for typos.
var commandText = string.Format("SELECT T1.IsoShtRevID, T1.LineID, T1.FileName, T1.Revision " +
"FROM dbo.PDSIsometricSheets T1 " +
"INNER JOIN (" +
"SELECT LineID, MAX(Revision) as MaxRevision " +
"FROM dbo.PDSIsometricSheets " +
"WHERE SchemaName='{0}' AND Revision <= 5 AND Revision >= 0" +
"GROUP BY LineID" +
") T2 " +
"ON T1.LineID = T2.LineID AND T1.Revision = T2.MaxRevision ", projectNo);

Categories

Resources