Simple query for getting max value for each entity - c#

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;

Related

How to combine multiple rows of a table to a single row in sql server and join to another table

How can i merge the rows of a teachers qualification from its table to a single row and join it to another so i can search for a given condition to know if a teacher possesses the given degree/certification. Or is there a better approach other than the one i am trying to use? Thanks in advance. Second image.
SELECT
StaffTable.TeacherType,
StaffTable.StaffID,
TeacherQualificationsTable.YearOfGraduation,
TeacherQualificationsTable.SubjectMajorsCombination,
STUFF((SELECT
', ' + [DegreeObtained]
FROM
TeacherQualificationsTable FOR XML PATH('')),1,1,'') AS [DegreeObtained]
FROM
StaffTable
INNER JOIN
TeacherQualificationsTable
ON
StaffTable.StaffID = TeacherQualificationsTable.StaffID
INNER JOIN
AppointmentChronologyTable ON StaffTable.StaffID = AppointmentChronologyTable.StaffID
WHERE
(StaffTable.TeacherType = #TeacherType)
AND (StaffTable.StaffStatus = #StaffStatus)
AND DegreeObtained NOT CONTAINS ('B.Ed (Bachelor of Education)' , 'M.Ed (Master of Education)', 'G.D.E (Graduate Diploma in Education)')
ORDER BY
StaffTable.LastName,
StaffTable.FirstName,
StaffTable.MiddleName
I have a staffTable and a staffQualificationsTable (which will have multiple qualification entries for any given staff). Am required to check if some staff have some given qualifications eg 'B.Ed (Bachelor of Education)' , 'M.Ed (Master of Education)', 'G.D.E (Graduate Diploma in Education)' and return all the staff without it so they will be called to tender theirs or laid off. Please, i hope this is clearer.

add column to existing query with GROUP BY

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.

Differentiating between 2 SQL column names with the same name in a C# SqlConnection

I have joined the same 2 tables twice using different aliases in a SQL query to enable me to select 2 (potentially but not always) different address ids which then link in to the address table.
SELECT C.court_id, C.court_name, CA.court_address, CA2.court_address...
FROM court C " +
JOIN court_addr CA ON C.court_addr_id = CA.court_addr_id " +
JOIN court_addr CA2 ON C.court_postal_addr_id = CA2.court_addr_id " + ...
Now when trying to output the results of this query using ASP.NET C# I'm unsure how to specify which of the two addresses to Response.Write. Putting the alias in front of the column name (as in the 4th string value below) doesn't work and brings up an error. Is there a way of differentiating between the two addresses in C# despite them both having the same column name in the database?
while (myDataReader.Read())
{
string court_id = myDataReader["court_id"].ToString();
string court_name = myDataReader["court_name"].ToString();
string court_address = myDataReader["court_address"].ToString();
string court_postal_address = myDataReader["CA2.court_address"].ToString();
etc.....
Thanking you muchly in advance
You should use an alias in your sql to distinguish them, then you will be able to return the correct value:
SELECT C.court_id,
C.court_name,
CA.court_address as CACourtAddress,
CA2.court_address as CA2CourtAddress
FROM court C " +
JOIN court_addr CA ON C.court_addr_id = CA.court_addr_id " +
JOIN court_addr CA2 ON C.court_postal_addr_id = CA2.court_addr_id " + ...
You should use alias name to distinguish two columns having same name like :
SELECT C.court_id, C.court_name, CA.court_address CourtAddress, CA2.court_address CourtPostalAddress FROM court C
JOIN court_addr CA ON C.court_addr_id = CA.court_addr_id
JOIN court_addr CA2 ON C.court_postal_addr_id = CA2.court_addr_id
And then in C# you can access them very easily :
string court_id = myDataReader["court_id"].ToString();
string court_name = myDataReader["court_name"].ToString();
string court_address = myDataReader["CourtAddress"].ToString();
string court_postal_address = myDataReader["CourtPostalAddress"].ToString();
I hope this helps solve your problem :)
you could access the columns via index if you cannot modify the query.
var foo = MyDataReader[0].ToString();
Or you could modify the query using the AS keyword in your sql statement.
SELECT foo AS bar FROM Baz
In addition to providing a column name alias as bluefeet suggests, another way would be to access the values by index instead of by name in C#.
string theValue = myReader[0] as string ?? String.Empty;
This, however, requires the order of the columns to never change and is thus to be used carefully. Also, this only works as you specifically select the columns by name in the given order in your SQL statement.
This may not work for a SELECT *, as the order of the returned columns is not fixed in a SELECT *.

SQL Query to access database

I'm writing a database query that will show me where there is a space for parking. It is only used in July.
There is one table that shows all the spaces and whether they are rented that day. There is another table that has the spaces and their sizes. I want to be able to select those spaces that are available on all the days within the selected time period and have the correct size.
I am having a problem, though, selecting only the spaces available within the given time period. Here is the query so far but it does not contain anything concerning the space size as I want this part to work first.
SELECT C.Plads, SUM[C.optaget] C.[ledlig] FROM
(SELECT Plads FROM OptagetPladser AS A Inner JOIN Bådpladser as B ON
A.plads=B.Pladsnummer
WHERE
(A.dato>=" + Startdato + "and A.dato<="+Slutdato+") //checking the time period
and (a.optaget = 0)) //0 means the space is availible
as C
GROUP BY C.Plads
HAVING SUM(C.optaget) >="+ diffResult+")";//diff result is the timespan
At the moment I'm getting the error
Syntax error (missing operator) in query expression 'SUM[C.optaget]'
Any ideas?
First of all, you should rework your SQL query - it contains too many simple errors.
Here are a few.
Try adding a ',' and make some changes in query:
SELECT C.Plads, SUM(C.optaget), C.ledlig FROM
Your subquery C doesn't have an optaget and ledlig fields too. To fix this add those fields right after sebquery's SELECT
Fix a syntax error here:
(A.dato>=" + Startdato + "and A.dato<="+Slutdato+") which should be:
(A.dato >= " + Startdato + " and A.dato <= "+Slutdato+")
Your last double quote is redundant as well as last ')'. Remove it:
HAVING SUM(C.optaget) >= "+ diffResult+" ;//diff result is the timespan
Below is how your SQL query should look. Please, note: there are still missing fields optaget and ledlig in subquery C.
SELECT C.Plads, SUM(C.optaget), C.ledlig FROM
(
SELECT Plads FROM OptagetPladser AS A
INNER JOIN Bådpladser as B
ON A.plads = B.Pladsnummer
WHERE (A.dato >= " + Startdato + " AND A.dato <= " + Slutdato + ")
AND (a.optaget = 0)
)
AS C
GROUP BY C.Plads
HAVING SUM(C.optaget) >= " + diffResult + ";
I believe, there could appear an architectural or performance issues, but without table data I can't say it for sure.

ASP .NET SQL Query SUM, TOTAL & NEW COLUMN

I have dwelling on this for hours and still cannot find out how to do this. How do you get the total sales of an item for every year.
What I have got so far is this:
SQLCommand.CommandText = #"SELECT SUM SalesNo AS TotalYearSales FROM SalesTable WHERE Product = " + ddItems.SelectedItem + "";.
The table headings are as follows Product, Year, SalesNo.
SQLCommand.CommandText = #"SELECT DatePart( YY, SalesDate ), SUM( SalesNo ) AS TotalYearSales FROM SalesTable WHERE Product = ? GROUP BY DatePart( YY, SalesDate ) ";
SQLCommand.Parameters.Add( "parmForProduct", ddItems.SelectedItem );
As Daniel pointed out, you would be wide open to sql-injection attacks and should parameterized queries.
To get total by year, you have to add the year as a basis of the query too. I don't know the "date" column in your table the transactions are based on, so you'll have to adjust. The "?" in the query is a "place-holder" for the parameter added immediately after.. And parameters should be added in the same order as listed in the query. Some SQL engines allow "named" parameters and use something like "#ProductIWant", and your parameter would use the same...
Since you are querying for only a specific product, that doesn't need to be in the list.. unless you wanted ALL products grouped by year.
Something Like
Select Year(SalesDate),Sum(SalesNo) From SalesTable where Product = "Navel Defluffer"
Group By Year(SalesDate)
and as #Daniel alluded to, use parameterised queries not string concatenation.

Categories

Resources