Trouble with aggregate in Where clause, Selecting Max(x) When Max(x) != 3 - sql

I am trying to reconfigure the below sql to only pull records when the Max(Field) != 3 but keep getting an error (detailed) below.
This is the code before adding the Where Max(field) != 3
SELECT P.Code,
MAX(PW.v1) AS V1
FROM SW
INNER JOIN S ON SW.S_Id = S.Id
INNER JOIN PW ON SW.PW_Id = PW.Id
INNER JOIN PON S.P_Id = P.id
WHERE S.P_Id = P.id
GROUP BY P.Code
My Attempt
SELECT P.Code,
MAX(PW.v1) AS V1
FROM SW
INNER JOIN S ON SW.S_Id = S.Id
INNER JOIN PW ON SW.PW_Id = PW.Id
INNER JOIN PON S.P_Id = P.id
WHERE S.P_Id = P.id
AND (SELECT MAX(PW.v1)
FROM SW AS SW2
WHERE SW.PWId = SW2.PW_Id) != 3
GROUP BY P.Code
This is the error I get and not sure what to do:
An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.

Traditional method of filtering on results of an aggregate can be achieved by using HAVING clause. I also removed the unnecessary WHERE clause as you already joined those 2 tables on that column. Here is the query:
SELECT P.Code
,MAX(PW.v1) AS V1
FROM SW
INNER JOIN S
ON SW.S_Id = S.Id
INNER JOIN PW
ON SW.PW_Id = PW.Id
INNER JOIN P
ON S.P_Id = P.id
GROUP BY P.Code
HAVING MAX(PW.v1)!=3;

Related

How to select top when already selected fields

Just wanted to ask how to add a 'select top 1 *' when I've already selected fields from a list? I seen examples in other codes but don't quite get it. Thought will be easier if see it in a code I constructed.
Below is an example of a query I have:
select frp.ProductPersonID,frp.FlightSeatId, frp.PlusMealId, per.TitleID, per.surname, per.FirstName, per.PersonTypeId, tor.PersonID, tor.Reference
from package pk
inner join product p on p.packageid = pk.packageid
inner join productperson pp on pp.productid = p.productid
inner join person per on per.personid = pp.personid
left join flightlogicalseat fls on fls.productpersonid = pp.productpersonid
inner join TourOperatorReference tor on tor.PersonID = per.PersonId
inner join FlightReservationPassenger frp on frp.ProductPersonID = pp.ProductPersonId
where pk.Reference LIKE '%'
and ProductTypeId =1
Simply try to use TOP keyword like this:
select TOP 1 frp.ProductPersonID,frp.FlightSeatId, frp.PlusMealId, per.TitleID,
You can just wrap your existing query in new query:
SELECT TOP 1 * FROM
(select frp.ProductPersonID,frp.FlightSeatId, frp.PlusMealId, per.TitleID, per.surname, per.FirstName, per.PersonTypeId, tor.PersonID, tor.Reference
from package pk
inner join product p on p.packageid = pk.packageid
inner join productperson pp on pp.productid = p.productid
inner join person per on per.personid = pp.personid
left join flightlogicalseat fls on fls.productpersonid = pp.productpersonid
inner join TourOperatorReference tor on tor.PersonID = per.PersonId
inner join FlightReservationPassenger frp on frp.ProductPersonID = pp.ProductPersonId
where pk.Reference LIKE '%'
and ProductTypeId =1) t

SQL nested aggregate function as subquery syntax error

I need to perform an average of averages. Figured out how to write the subquery, but the final function throws two errors. Syntax error on line 15 and then on line 1.
The subquery works. I then just need an average of the averages of the products in the same category. What's missing?
SELECT
c."name",
AVG(avgvalue)
FROM
(SELECT
c.name,
p.name,
AVG(a."value") AS avgvalue
FROM
answers a
INNER JOIN
survey_responses sr ON sr.id = a.survey_response_id
AND a.question_id = 13
INNER JOIN
answers category_answer ON category_answer.survey_response_id = sr.id
AND category_answer.question_id = 264
INNER JOIN
answers_categories ac ON category_answer.id = ac.answer_id
INNER JOIN
categories c ON c.id = ac.category_id
INNER JOIN
products p ON p.id = a.product_id
WHERE
c.name IN ('Accounting')
HAVING
count(p.name) > 10) AS ProductAverages
GROUP BY c.NAME
Remove ; after the HAVING clause in the temporary table
HAVING count(p.name)>10

Join with comma-separated data returned from function using SQL

I am trying hard on this, but I am unable to solve it. I have data coming comma-separated from a column, and I am splitting it with a function, and I need to return all comma-separated values.
I am doing something like outer join ApplicationDocument Table.
Here is the query:
SELECT PA.Id,
Ad.Id,
Ad.DocumentTitle,
Ad.Path
,
S.value
FROM dbo.ApplicationDocument AS Ad
right JOIN dbo.PostApplication AS PA
ON Ad.ApplicationId = PA.Id
JOIN dbo.Post P
ON PA.JobId = P.Id
outer APPLY dbo.fnSplit(P.RequiredDocuments,',') as S
WHERE S.Value = Ad.DocumentTitle
CROSS APPlY (select value
from dbo.fnSplit(P.RequiredDocuments,',')
WHERE Value =Ad.DocumentTitle) as S
SELECT PA.Id,
Ad.Id,
Ad.DocumentTitle,
Ad.Path,
X.Value
FROM dbo.ApplicationDocument AS Ad
JOIN dbo.PostApplication AS PA
ON Ad.ApplicationId = PA.Id
JOIN dbo.Post P
ON PA.JobId = P.Id
OUTER APPLY
(SELECT Value FROM dbo.fnSplit(P.RequiredDocuments,',') as S
WHERE S.Value = Ad.DocumentTitle) X
I came up with the follwing query by the help of #Humpty Dumpty and #t-clausen-dk.
Here is what I needed. This query now fetches all the records, and I can now filter using a where clause on it.
SELECT PA.Id AS ApplicationId,
Ad.Id AS ApplicationDocumentId,
Ad.DocumentTitle,
Ad.Path,
S.value
FROM dbo.ApplicationDocument AS Ad
right JOIN dbo.PostApplication AS PA
ON Ad.ApplicationId = PA.Id
JOIN dbo.Post P
ON PA.JobId = P.Id
cross APPLY dbo.fnSplit(P.RequiredDocuments,',') as S
where PA.Id = SomeId here
Check the parenthesis, ')'. It's not properly used:
SELECT PA.Id,Ad.Id,Ad.DocumentTitle,Ad.Path
FROM dbo.ApplicationDocument AS Ad
INNER JOIN dbo.PostApplication AS PA
ON Ad.ApplicationId = PA.Id
INNER JOIN dbo.Post P
ON PA.JobId = P.Id
CROSS APPlY (select value from dbo.fnSplit(P.RequiredDocuments,',')
WHERE Value =Ad.DocumentTitle))

Error: Cannot use an aggregate or a subquery in an expression used for the group by list

I'm getting this error: Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause.
I searched on internet, but i don't know how to apply the correction in my case. I found different types of query only.
I'm trying to get a Count result in a field (line 5), but when I add the Count query i'm getting this error.
I'm using SQL SERVER 2008 R2.
When I remove the Count from SELECT and GROUP BY the query run correctly.
SELECT TF.COD_FORNECEDOR AS 'Cód. Fornec.',
TF.NOM_FANTASIA AS 'Fornecedor',
DM.COD_CONTRATO_RELACIONADO AS 'CONTRATO',
UA2.NOM_USUARIO AS 'NOM_USUARIO_COMPRADOR',
(SELECT COUNT(COD_CONTRATO_RELACIONADO) FROM TB_DEMANDA D INNER JOIN TB_PROCESSO P ON D.COD_CONTRATO_RELACIONADO = P.NUM_CONTRATO WHERE D.COD_CONTRATO_RELACIONADO = DM.COD_CONTRATO_RELACIONADO) AS 'NUM_ADITIVO',
0 AS 'Qtd. Aditivo',
SUM(DM.VAL_TOTAL_ORCADO) AS 'Valor Inicial',
SUM(TP.VAL_CONTRATADO) AS 'Valor Final',
((SUM(TP.VAL_CONTRATADO) / SUM(DM.VAL_TOTAL_ORCADO)) -1) * 100 AS 'Var. %'
FROM TB_FORNECEDOR TF
LEFT JOIN TB_DEMANDA DM ON DM.COD_FORNECEDOR = TF.COD_FORNECEDOR
LEFT JOIN TB_PROCESSO TP ON DM.COD_DEMANDA = TP.COD_DEMANDA
LEFT JOIN TB_PROCESSO_FORNECEDOR PF ON PF.COD_PROCESSO = TP.COD_PROCESSO
LEFT JOIN USUARIO UA ON UA.NUM_USUARIO = DM.NUM_USUARIO_COMPRADOR
LEFT JOIN USUARIO UA2 ON UA2.NUM_USUARIO = DM.NUM_USUARIO_COMPRADOR
LEFT JOIN TB_STATUS_DEMANDA_DATA SD ON SD.COD_DEMANDA = DM.COD_DEMANDA
LEFT JOIN TB_BASELINE BA ON BA.COD_PROCESSO = TP.COD_PROCESSO
LEFT JOIN TB_BASELINE_TAREFAS BT ON BT.COD_BASELINE = BA.COD_BASELINE AND BT.COD_PROCESSO = BA.COD_PROCESSO
LEFT JOIN TB_STATUS_PROCESSO SP ON SP.COD_STATUS = SD.COD_STATUS
LEFT JOIN TB_MEDIO_STATUS MS ON MS.COD_MEDIO_STATUS = SP.COD_MEDIO_STATUS
left JOIN #TB_PROCESSO TT ON TT.COD_PROCESSO = TP.COD_PROCESSO
GROUP BY
TF.COD_FORNECEDOR,
TF.NOM_FANTASIA,
DM.COD_CONTRATO_RELACIONADO,
UA2.NOM_USUARIO,
(SELECT COUNT(COD_CONTRATO_RELACIONADO) FROM TB_DEMANDA D INNER JOIN TB_PROCESSO P ON D.COD_CONTRATO_RELACIONADO = P.NUM_CONTRATO WHERE D.COD_CONTRATO_RELACIONADO = DM.COD_CONTRATO_RELACIONADO)
ORDER BY TF.NOM_FANTASIA
Try this:
SELECT TF.COD_FORNECEDOR AS 'Cód. Fornec.',
TF.NOM_FANTASIA AS 'Fornecedor',
DM.COD_CONTRATO_RELACIONADO AS 'CONTRATO',
UA2.NOM_USUARIO AS 'NOM_USUARIO_COMPRADOR',
sq.cnt AS 'NUM_ADITIVO',
0 AS 'Qtd. Aditivo',
SUM(DM.VAL_TOTAL_ORCADO) AS 'Valor Inicial',
SUM(TP.VAL_CONTRATADO) AS 'Valor Final',
((SUM(TP.VAL_CONTRATADO) / SUM(DM.VAL_TOTAL_ORCADO)) -1) * 100 AS 'Var. %'
FROM TB_FORNECEDOR TF
LEFT JOIN TB_DEMANDA DM ON DM.COD_FORNECEDOR = TF.COD_FORNECEDOR
LEFT JOIN TB_PROCESSO TP ON DM.COD_DEMANDA = TP.COD_DEMANDA
LEFT JOIN TB_PROCESSO_FORNECEDOR PF ON PF.COD_PROCESSO = TP.COD_PROCESSO
LEFT JOIN USUARIO UA ON UA.NUM_USUARIO = DM.NUM_USUARIO_COMPRADOR
LEFT JOIN USUARIO UA2 ON UA2.NUM_USUARIO = DM.NUM_USUARIO_COMPRADOR
LEFT JOIN TB_STATUS_DEMANDA_DATA SD ON SD.COD_DEMANDA = DM.COD_DEMANDA
LEFT JOIN TB_BASELINE BA ON BA.COD_PROCESSO = TP.COD_PROCESSO
LEFT JOIN TB_BASELINE_TAREFAS BT ON BT.COD_BASELINE = BA.COD_BASELINE AND BT.COD_PROCESSO = BA.COD_PROCESSO
LEFT JOIN TB_STATUS_PROCESSO SP ON SP.COD_STATUS = SD.COD_STATUS
LEFT JOIN TB_MEDIO_STATUS MS ON MS.COD_MEDIO_STATUS = SP.COD_MEDIO_STATUS
LEFT JOIN #TB_PROCESSO TT ON TT.COD_PROCESSO = TP.COD_PROCESSO
LEFT JOIN (
SELECT D.COD_CONTRATO_RELACIONADO, COUNT(COD_CONTRATO_RELACIONADO) AS cnt
FROM TB_DEMANDA D
INNER JOIN TB_PROCESSO P ON D.COD_CONTRATO_RELACIONADO = P.NUM_CONTRATO
GROUP BY D.COD_CONTRATO_RELACIONADO
) sq ON sq.COD_CONTRATO_RELACIONADO = DM.COD_CONTRATO_RELACIONADO
GROUP BY
TF.COD_FORNECEDOR,
TF.NOM_FANTASIA,
DM.COD_CONTRATO_RELACIONADO,
UA2.NOM_USUARIO,
sq.cnt
ORDER BY TF.NOM_FANTASIA
I integrated the num_aditivo subquery in a LEFT JOIN.

sql query sum bringing back different results

I have the following two queries below, the Total is coming back different, but I am adding the sums in each of the query the same way. Why is the total coming back different?
select [Total Children] = (SUM(demo.NumberOfPreschoolers) + SUM(demo.NumberOfToddlers) + SUM(demo.NumberOfInfants)),
County = co.Description
from ClassroomDemographics as demo
inner join Classrooms as c on demo.Classroom_Id = c.Id
inner join Sites as s on c.Site_Id = s.Id
inner join Profiles as p on s.Profile_Id = p.Id
inner join Dictionary.Counties as co on p.County_Id = co.Id
where co.Description = 'MyCounty'
Group By co.Description
select [Number Of DLL Children] = SUM(cd.NumberOfLanguageSpeakers),
[Total Children] = (SUM(demo.NumberOfPreschoolers) + SUM(demo.NumberOfToddlers) + SUM(demo.NumberOfInfants)),
County = co.Description
from ClassroomDLL as cd
inner join Classrooms as c on cd.Classroom_Id = c.Id
inner join Sites as s on c.Site_Id = s.Id
inner join Profiles as p on s.Profile_Id = p.Id
inner join Dictionary.Counties as co on p.County_Id = co.Id
inner join ClassroomDemographics as demo on c.Id = demo.Classroom_Id
where co.Description = 'MyCounty'
Group by co.Description
Just a quick glance over the two querties, I would presume that:
inner join ClassroomDemographics as demo on c.Id = demo.Classroom_Id
in the second query is excluding results that are in the first query, therefor the aggregated values will be different.
Your join to the Classrooms table is joining with an extra table in the 2nd query.
Query 1:
from ClassroomDemographics as demo
inner join Classrooms as c on demo.Classroom_Id = c.Id
Query 2:
from ClassroomDLL as cd
inner join Classrooms as c on cd.Classroom_Id = c.Id
...
inner join ClassroomDemographics as demo on c.Id = demo.Classroom_Id
My bet is that the ClassroomDLL table has less data in it, or has rows with a null for one of the join criteria columns, either of which could exclude rows from the results and throw your aggregate totals off.