This query works fine only without WHERE
, otherwise there is an error:
column "cnt" does not exist
SELECT
*,
(SELECT count(*)
FROM B
WHERE A.id = B.id) AS cnt
FROM A
WHERE cnt > 0
This query works fine only without WHERE
, otherwise there is an error:
column "cnt" does not exist
SELECT
*,
(SELECT count(*)
FROM B
WHERE A.id = B.id) AS cnt
FROM A
WHERE cnt > 0
Use a subquery:
SELECT a.*
FROM (SELECT A.*,
(SELECT count(*)
FROM B
WHERE A.id = B.id
) AS cnt
FROM A
) a
WHERE cnt > 0;
Column aliases defined in the SELECT
cannot be used by the WHERE
(or other clauses) for that SELECT
.
Or, if the id on a
is unique, you can more simply do:
SELECT a.*, COUNT(B.id)
FROM A LEFT JOIN
B
ON A.id = B.id
GROUP BY A.id
HAVING COUNT(B.id) > 0;
Or, if you don't really need the count, then:
select a.*
from a
where exists (select 1 from b where b.id = a.id);
You need all columns from A
in the result, plus the count from B
. That's what your demonstrated query does.
You only want rows with cnt > 0
. That's what started your question after all.
Most or all B.id
exist in A
. That's the typical case and certainly true if a FK constraint on B.id
references to A.id
.
Faster, shorter, correct:
SELECT * -- !
FROM (SELECT id, count(*) AS cnt FROM B) B
JOIN A USING (id) -- !
-- WHERE cnt > 0 -- this predicate is implicit now!
Aggregate before the join, that's typically (substantially) faster when processing the whole table or major parts of it. It also defends against problems if you join to more than one n-table. See:
You don't need to add the predicate WHERE cnt > 0
any more, that's implicit with the [INNER] JOIN
.
You can simply write SELECT *
, since the join only adds the column cnt
to A.*
when done with the USING
clause - only one instance of the joining column(s) (id
in the example) is added to the out columns. See:
postgres really allows to have outside aggregate function attributes that are not behind group by?
That's only true if the PK column(s) is listed in the GROUP BY
clause - which covers the whole row. Not the case for a UNIQUE
or EXCLUSION
constraint. See:
SQL Fiddle demo (extended version of Gordon's demo).