I have a question regarding my SQL query. Below you will see my database:
And I have the following query right now:
SELECT enquete_vraag,enquete_antwoord,docent,vak,semesterstart
FROM ENQUETE_ANTWOORD
LEFT JOIN KDV ON ENQUETE_ANTWOORD.kdv_ID = KDV.kdv_ID
LEFT JOIN DOCENT ON KDV.docent_ID = DOCENT.docent_ID
LEFT JOIN VAK ON KDV.vak_ID = VAK.vak_ID
LEFT JOIN ENQUETE_VRAAG ON ENQUETE_ANTWOORD.enquete_vraag_ID = ENQUETE_VRAAG.enquete_vraag_ID
WHERE DOCENT.docent_ID = variableDocentID AND VAK.vak = variableVak
And I display the returned data in a datagridview:
Now the datagridview shows all questions that are being answered by all students. What I want is the average for each question and only show that. So you have 1 row that has question 6 with the average answer and question 7 with the average answer and so on, how do I achieve that in my SQL query?
hi you should do something like this
SELECT enquete_vraag,AVG(enquete_antwoord) enquete_antwoord,docent,vak,semesterstart
FROM ENQUETE_ANTWOORD
LEFT JOIN KDV ON ENQUETE_ANTWOORD.kdv_ID = KDV.kdv_ID
LEFT JOIN DOCENT ON KDV.docent_ID = DOCENT.docent_ID
LEFT JOIN VAK ON KDV.vak_ID = VAK.vak_ID
LEFT JOIN ENQUETE_VRAAG ON ENQUETE_ANTWOORD.enquete_vraag_ID = ENQUETE_VRAAG.enquete_vraag_ID
WHERE DOCENT.docent_ID = variableDocentID AND VAK.vak = variableVak
GROUP BY enquete_vraag, docent,vak,semesterstart
SELECT enquete_vraag,AVG(enquete_antwoord) as [enquete_antwoord]
FROM ...
GROUP BY enquete_vraag
The problem then, of course, becomes which vak etc to choose.... Because of translation, it is not easy for me to guess at which value means what, so it is hard to advise on that. You might be able to include the extra values in the GROUP BY clause (if they are the same for all the matching rows); or you might be able to take a MIN / MAX.
just add avg function in your code.
...AVG(enquete_antwoord)...
write above code it gives you the correct answer
Related
The explanation is a little long but I want to make me understand with the problem as detailed as possible. I have 4 tables, 2 indicate the information of material used and material returned (Transactions and Returns) and the other 2 tablan detail what material was used or was returned (Trans_det1 and Devol_det1)
Each material that is used or not is detailed by boletas(tickets), which are detailed by work orders, an example:
I have the following sentences:
--REGISTRATION OF INCOME
SELECT*FROM Transa WHERE orden='GORE-999888'
--REGISTRATION OF RETURNS
SELECT*FROM Devol WHERE orden='GORE-999888'
It returns this:
The Transa table returns all the tickets that were used for that order and Devol also but shows me the boletas(tickets) that were used to return material.
MATERIALS DETAILS
--WHAT WAS USED
SELECT Transa_det1.boleta, Transa_det1.rollo, Transa_det1.cantidad FROM Transa_det1,Transa
WHERE Transa.boleta=Transa_det1.boleta AND orden='GORE-999888'
--WHAT WAS RETURNED
SELECT Devol_det1.boleta, Devol_det1.rollo, Devol_det1.cantidad FROM Devol_det1, Devol
WHERE Devol_det1.boleta=Devol.boleta AND orden='GORE-999888'
It returns this:
It returns the rollos that were used in the tickets from order XXXX and how much was used, the second table shows me the number of rollos that were returned.
My question, for the RT0102 rollo I am using 100.5 but then I returned 100 at the end what I really used was 0.5, same for RT0103 use 250 but then I returned 50, there is a way to do the subtraction if the rollo match while they are of the same order all in a single query? I mean I need a way to return this:
RT0103 0.5
RT0102 200
FH0091 465.75 //DON'T SUFFER CHANGES BECAUSE I DIDN'T RETURN THIS MATERIAL
You can use OUTER APPLY like following.
SELECT td.boleta,
td.rollo,
td.cantidad,
( td.cantidad - Isnull(c.ret, 0) ) AS Returned
FROM transa_det1 td
INNER JOIN transa ta
ON ta.boleta = td.boleta
OUTER apply (SELECT top 1 d1.cantidad AS Ret
FROM devol_det1 d1
INNER JOIN devol d
ON d1.boleta = d.boleta
WHERE d1.rollo = td.rollo and d.orden=ta.orden)c
where ta.orden = 'GORE-999888'
One suggestion, always use JOINS, this makes your query more readable and makes it look very clear as to which join corresponds to which condition.
Below would be the query to get the expected results, You can use case statement for
select t1.rollo,
case when t2.cantidad is null then 0 // if canditad does not have value in DevolDtl then return 0 else do the subtraction
else t1.cantidad-t2,canditad end as result from
(
SELECT Transa_det1.boleta, Transa_det1.rollo, Transa_det1.cantidad FROM Transa_det1,Transa
WHERE Transa.boleta=Transa_det1.boleta AND orden='GORE-999888') t1
left outer join
(
SELECT Devol_det1.boleta, Devol_det1.rollo, Devol_det1.cantidad FROM Devol_det1, Devol
WHERE Devol_det1.boleta=Devol.boleta AND orden='GORE-999888') t2
on t1.boleta=t2.boleta;
I am writing a small app (c#/WPF/MySQL). One of things that I want to do is to update some product descriptions within a table.
Here is a slightly altered version of the query that I thought could be the starting point:
SELECT
`egx_machine`.`contact_id` AS `contact_id`,
`egx_machine`.`gtr2_product_family` AS `gtr2_product_family`,
`egx_machine`.`gtr2_product_family_factory` AS `gtr2_product_family_factory`,
`egx_machine`.`gtr2_product_family_model` AS `gtr2_product_family_model`,
`egx_machine`.`gtr2_product_family_size` AS `gtr2_product_family_size`,
`egx_machine_extra`.`contact_name` AS `contact_name`,
`gtxuk_r2_machine`.`machine_desc` AS `machine_desc`,
`gtxuk_r2_machine`.`product_family` AS `product_family`,
`gtxuk_r2_machine`.`factory` AS `factory`,
`gtxuk_r2_machine`.`model` AS `model`,
`gtxuk_r2_machine`.`size` AS `size`
FROM (((`egx_machine`
JOIN `egx_machine_extra`
ON ((`egx_machine`.`contact_id` = `egx_machine_extra`.`contact_id`)))
JOIN `gtxuk_machine`
ON ((`egx_machine_extra`.`contact_value` = `gtxuk_machine`.`machine_id`)))
JOIN `gtxuk_r2_machine`
ON ((CONVERT(`gtxuk_machine`.`machine_desc` USING utf8) = `gtxuk_r2_machine`.`machine_desc`)))
WHERE (`egx_machine_extra`.`contact_name` = 'mac_type')
But somehow, I need to turn this into an update query where:
`egx_machine`.`gtr2_product_family` = `gtxuk_r2_machine`.`product_family`
and
`egx_machine`.`gtr2_product_family_factory = `gtxuk_r2_machine`.`factory`
I know it's a bit long winded - but I started off with a full head of hair and now look like kojak.
If you want to update the values in the product table you can do as
update
products p
join products_new_data pn on pn.product_name = p.product_name
set
p.product_name_new = pn.product_name_new ,
p.product_source = pn.product_source ;
For doing it reverse you can do as
update
products_new_data pn
join products p on p.product_name = pn.product_name
set
pn.product_name_new = p.product_name_new,
pn.product_source = p.product_source ;
UPDATE
From the comments I guess this is what you are looking at, however its really hard to write a query without the schema and some data, but I think this should be pretty close what you are looking at if I am not misunderstood your question
update egx_machine em
JOIN egx_machine_extra emx on emx.contact_id = em.contact_id
JOIN gtxuk_machine gm on emx.contact_value = gm.machine_id
JOIN gtxuk_r2_machine g2m on CONVERT(gm.machine_desc USING utf8) = g2m.machine_desc
set
em.gtr2_product_family = g2m.product_family ,
em.gtr2_product_family_factory = g2m.factory
I am trying to get pairs of measurement for two different devices, joined on equal Timestamps. In SQL, this works as expected:
select
leftItem.Timestamp, leftItem.Value, rightItem.Value
from
DataTable leftItem
inner join DataTable rightItem
on leftItem.Timestamp = rightItem.Timestamp
where
leftItem.Device = 1 and rightItem.Device = 2
But if I try to convert it to HQL:
select
left, right
from
DataTable as left
inner join DataTable as right
on left.Timestamp = right.Timestamp
where
left.Device = 1 and right.Device = 2
I get a NHibernate.Hql.Ast.ANTLR.SemanticException:
Path expected for join!
How do I specify a "path" to the same table?
In HQL, joins can only be done on associations between entities. If you want a join on something else, the only possibility is to make the join in the where clause:
select left, right
from
DataTable as left, DataTable as right
where
left.Timestamp = right.Timestamp
and left.Device = 1
and right.Device = 2
This is my sql code
SELECT M.PartNo AS ModulePartNo,
(SELECT SUM(Delivered - Allocated)
FROM V_InStock Stk
WHERE Stk.PartNo = M.PartNo) AS Available
FROM V_Products M
WHERE M.PartNo='100-25897'
I am having real problems getting this to work in Linq, can't work out the sum part - any help would be really appreciated
This should work.
var query = from stk in V_InStock
group stk by stk.PartNo into stkg
where stkg.Key == '100-25897'
select new
{
ModulePartNo = stkg.Key,
Available = stkg.Sum(s => s.Delivered) - stkg.Sum(s => s.Allocated)
}
If you need to do aggregate grouping etc you will probably need to set up an object to "select" everything into. However for a straight join something like this should work.
var outputObject = (from t1 in dbContext.table1
join t2 in dbContext.table2 on t1.PartNo equals t2.PartNo
select (t1.Delivered - t2.Allocated));
I have the following LINQ query, that is returning the results that I expect, but it does not "feel" right.
Basically it is a left join. I need ALL records from the UserProfile table.
Then the LastWinnerDate is a single record from the winner table (possible multiple records) indicating the DateTime the last record was entered in that table for the user.
WinnerCount is the number of records for the user in the winner table (possible multiple records).
Video1 is basically a bool indicating there is, or is not a record for the user in the winner table matching on a third table Objective (should be 1 or 0 rows).
Quiz1 is same as Video 1 matching another record from Objective Table (should be 1 or 0 rows).
Video and Quiz is repeated 12 times because it is for a report to be displayed to a user listing all user records and indicate if they have met the objectives.
var objectiveIds = new List<int>();
objectiveIds.AddRange(GetObjectiveIds(objectiveName, false));
var q =
from up in MetaData.UserProfile
select new RankingDTO
{
UserId = up.UserID,
FirstName = up.FirstName,
LastName = up.LastName,
LastWinnerDate = (
from winner in MetaData.Winner
where objectiveIds.Contains(winner.ObjectiveID)
where winner.Active
where winner.UserID == up.UserID
orderby winner.CreatedOn descending
select winner.CreatedOn).First(),
WinnerCount = (
from winner in MetaData.Winner
where objectiveIds.Contains(winner.ObjectiveID)
where winner.Active
where winner.UserID == up.UserID
orderby winner.CreatedOn descending
select winner).Count(),
Video1 = (
from winner in MetaData.Winner
join o in MetaData.Objective on winner.ObjectiveID equals o.ObjectiveID
where o.ObjectiveNm == Constants.Promotions.SecVideo1
where winner.Active
where winner.UserID == up.UserID
select winner).Count(),
Quiz1 = (
from winner2 in MetaData.Winner
join o2 in MetaData.Objective on winner2.ObjectiveID equals o2.ObjectiveID
where o2.ObjectiveNm == Constants.Promotions.SecQuiz1
where winner2.Active
where winner2.UserID == up.UserID
select winner2).Count(),
};
You're repeating join winners table part several times. In order to avoid it you can break it into several consequent Selects. So instead of having one huge select, you can make two selects with lesser code. In your example I would first of all select winner2 variable before selecting other result properties:
var q1 =
from up in MetaData.UserProfile
select new {up,
winners = from winner in MetaData.Winner
where winner.Active
where winner.UserID == up.UserID
select winner};
var q = from upWinnerPair in q1
select new RankingDTO
{
UserId = upWinnerPair.up.UserID,
FirstName = upWinnerPair.up.FirstName,
LastName = upWinnerPair.up.LastName,
LastWinnerDate = /* Here you will have more simple and less repeatable code
using winners collection from "upWinnerPair.winners"*/
The query itself is pretty simple: just a main outer query and a series of subselects to retrieve actual column data. While it's not the most efficient means of querying the data you're after (joins and using windowing functions will likely get you better performance), it's the only real way to represent that query using either the query or expression syntax (windowing functions in SQL have no mapping in LINQ or the LINQ-supporting extension methods).
Note that you aren't doing any actual outer joins (left or right) in your code; you're creating subqueries to retrieve the column data. It might be worth looking at the actual SQL being generated by your query. You don't specify which ORM you're using (which would determine how to examine it client-side) or which database you're using (which would determine how to examine it server-side).
If you're using the ADO.NET Entity Framework, you can cast your query to an ObjectQuery and call ToTraceString().
If you're using SQL Server, you can use SQL Server Profiler (assuming you have access to it) to view the SQL being executed, or you can run a trace manually to do the same thing.
To perform an outer join in LINQ query syntax, do this:
Assuming we have two sources alpha and beta, each having a common Id property, you can select from alpha and perform a left join on beta in this way:
from a in alpha
join btemp in beta on a.Id equals btemp.Id into bleft
from b in bleft.DefaultIfEmpty()
select new { IdA = a.Id, IdB = b.Id }
Admittedly, the syntax is a little oblique. Nonetheless, it works and will be translated into something like this in SQL:
select
a.Id as IdA,
b.Id as Idb
from alpha a
left join beta b on a.Id = b.Id
It looks fine to me, though I could see why the multiple sub-queries could trigger inefficiency worries in the eyes of a coder.
Take a look at what SQL is produced though (I'm guessing you're running this against a database source from your saying "table" above), before you start worrying about that. The query providers can be pretty good at producing nice efficient SQL that in turn produces a good underlying database query, and if that's happening, then happy days (it will also give you another view on being sure of the correctness).