SQL-Server An aggregate (Count) may not appear in WHERE - sql

Im my query I get the following error message:
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.
My query is following:
SELECT f.ID as IdFlight
From Flights as f
inner join BookingsFlightsPassenger as b on f.ID = b.ID_flight
WHERE count(b.ID_Flight)<100
How can I solve this? I am not sure what the error message is suggesting

replace "where" by "having" and add group by
SELECT f.ID as IdFlight
From Flights as f inner join BookingsFlightsPassenger as b on f.ID = b.ID_flight
group by f.id
having count(b.ID_Flight)<100

The most efficient way to write this query doesn't use a join:
SELECT bfp.ID_flight as as IdFlight
FROM BookingsFlightsPassenger bfp
GROUP BY bfp.ID_flight
WHERE count(*) < 100;

Related

Is there any alternative way for following query in oracle

select
a.id,
a.name,
b.group,
a.accountno,
(
select ci.cardno
from taccount ac, tcardinfo ci
where ac.accountno = ci.accountno
) as card_no
from tstudent a, tgroup b
where a.id = b.id
And how to select more than one field from (select ci.cardno from taccount ac,tcardinfo ci where ac.accountno = ci.accountno) or any others way
Please note that the is not a relation in two queries (main and subquery). Sub-query value depends on the data of the main query. Main query is set of data by joining multiple table and sub-query is also a set of data by joining multiple table
In essence, you are describing a lateral join. This is available in oracle since version 12.
Your query is rather unclear about from which table each column comes from (I made assumptions, that you might need to review), and you seem to be missing a join condition in the subquery (I added question marks in that spot)... But the idea is:
select
s.id,
s.name,
g.group,
s.accountno,
x.*
from tstudent s
inner join tgroup g on g.id = s.id
outer apply (
select ci.cardno
from taccount ac
inner join tcardinfo ci on ????
where ac.accountno = s.accountno
) x
You can then return more columns to the subquery, and then will show up in the resultset.

Returning count using multiple subqueries

Forgive my ignorance, but sql-server is not my strong suit. I'm trying to retrieve the count of rows from two mapping tables using subqueries (correlated subqueries?). If I remove one subquery, things work fine, but if I include both subqueries, I'm not getting the expected number of rows back.
SELECT
a.id,
a.name,
al_1.locationid as LocationCount,
af_1.FuncAreaId as FuncAreaCount
FROM
application as a inner join
applicationlocation as al_1 on a.id = al_1.appid inner join
applicationfuncarea as af_1 on a.id = af_1.AppId
WHERE
al_1.locationid in
(
SELECT count(locationid)
FROM applicationlocation as al_2
WHERE al_2.appid = al_1.appid
)
AND
af_1.funcareaid in
(
SELECT count(funcareaid)
FROM applicationfuncarea as af_2
WHERE af_2.appid = af_1.appid
)
If I'm not mistaken about what you want to achieve here, then this can be achieved by using grouping with COUNT and DISTINCT operators:
SELECT
a.id,
a.name,
COUNT(DISTINCT al_1.locationid) as LocationCount,
COUNT(DISTINCT af_1.FuncAreaId) as FuncAreaCount
FROM
application as a inner join
applicationlocation as al_1 on a.id = al_1.appid inner join
applicationfuncarea as af_1 on a.id = af_1.AppId
GROUP BY a.id, a.name
It is hard to tell if result is correct without seeing your data and expected result. If the above does not work, try removing DISTINCT operators and see if you get the results that you need.

GROUP BY not working in left join query

I m trying to use group by clause in left join sql query and it is not working.
Please help me out, thanks in advance.
SELECT Cust_Mst_Det.Cust_Hd_Code,
Cust_Mst_Det.First_Name,
SL_HEAD20152016.vouch_date AS invoice_2,
SL_HEAD20142015.vouch_date AS invoice_1,
Cust_Mst_Hd.EMail
FROM Cust_Mst_Det
LEFT JOIN SL_HEAD20142015 ON Cust_Mst_Det.Cust_Hd_Code=SL_HEAD20142015.Member_Code
LEFT JOIN SL_HEAD20152016 ON Cust_Mst_Det.Cust_Hd_Code=SL_HEAD20152016.Member_Code
LEFT JOIN Cust_Mst_Hd ON Cust_Mst_Det.Cust_Hd_Code=Cust_Mst_Hd.Cust_Hd_Code
WHERE cust_mst_det.first_name!='NIL'
GROUP BY Cust_Mst_Det.Cust_Hd_Code
ORDER BY SL_HEAD20152016.vouch_date DESC,
SL_HEAD20142015.vouch_date
I'm not sure which DBMS you are using, but on an Oracle your query will not work at all.
First issue: The GROUP BY statement is used in conjunction with the aggregate functions to group the result-set by one or more columns. You do not have any aggregating function in your SELECT statement (count, max, etc.)
Second issue: you must specify all columns from SELECT statement in your GROUP BY statement (excluding columns that represents results of aggregation).
As I said I don't know which DB is used by you, but those two points should be applicable for the most of SQL standards.
It appears that it is impossible to use an ORDER BY on a GROUP BY summarisation. My fundamental logic is flawed. I will need to run the following subquery.
ex :
SELECT p.*, pp.price
FROM products p
LEFT JOIN ( SELECT price FROM product_price ORDER BY date_updated DESC ) pp
ON p.product_id = pp.product_id GROUP BY p.product_id;
This will take a performance hit but as it is the same subquery for each row it shouldn't be too bad.

SQL Beginner - How to get items from Table1 that are associated with at least 10 items in Table2

This is probably very easy, but I'm confused after looking at things online. Each item in my Contract table has multiple Envelopes. I want to find Contracts that have at least 10 envelopes. How do I go about this?
I've tried the following
select c.*, COUNT(e.ID)
from [Contract] c
INNER JOIN Envelope e ON e.ContractID = c.ID
Group By c.ID
HAVING Count(e.ID) > 10
And I get
Column 'Contract.PresenterUserID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I haven't dealt with aggregate or group by clauses before, so I'm not sure what it means.
By default, MySQL will accept your query. So, I am assuming that you are not using MySQL or the system has full group by turned on.
Here is another approach that will work in any database:
select c.*, e.cnt
from [Contract] c inner join
(select e.ContractId, count(*) as cnt
from Envelope e
group by e.ContractId
having count(*) >= 10
) e
on e.ContractID = c.ID;
This moves the aggregation to a subquery, before the join. You can then take all the columns from the contract table.
You are pretty close. You must include all fileds in the selectt either an aggregate function or the GROUP BY clause. Try this:
select c.id, c.PresenterUserID, COUNT(e.ID)
from [Contract] c
INNER JOIN Envelope e ON e.ContractID = c.ID
Group By c.ID, c.PresenterUserID
HAVING Count(e.ID) >= 10

Error in query: aggregate function or the GROUP BY clause

Hi all I have a problem with an SQL query: the problem is that if i add GROUP BY the database engine outputs the error:
Column 'dbo.classes.class_name' is invalid in the select list because
it is not contained in either an aggregate function or the GROUP BY clause.
My query is:
string query = "SELECT p.*
FROM dbo.classes AS p INNER JOIN teacher_classes AS a
ON a.class_id = p.class_id
and teach_id = #id
GROUP BY p.class_id";
Is there any help please for that.
Note without group by the query work fine but the result not grouped.
Your query is:
SELECT p.*
FROM dbo.classes AS p INNER JOIN
teacher_classes AS a
ON a.class_id = p.class_id and teach_id = #id
GROUP BY p.class_name;
You are trying to select all the columns from p and yet you're are grouping by class_name. This is not allowed in most databases. What happens if you have two classes, but information is different from them?
One option is to use distinct rather than group by to remove duplicates:
SELECT distinct c.*
FROM dbo.classes c INNER JOIN
teacher_classes tc
ON tc.class_id = c.class_id and tc.teach_id = #id;
Another option is to use something like in to find the matching classes for the teacher:
select c.*
from classes c
where c.class_id in (select tc.class_id from teacher_classes where teach_id = #id)
Notice I also changed your aliases so they have some relationship to the table names. This makes the query much easier to read.