SQL Server Select COUNT(*) in MSSQL without FROM

wvyml7n5  于 2023-11-16  发布在  其他
关注(0)|答案(2)|浏览(119)

Why does it output 1?

select count(*)

Why will this work?

SELECT 'penguins'
WHERE 1 = 2
HAVING 0 < 1;

Why doesn't it work? I mean, why doesn't it give out a 1 similarly to "penguins"?

select count(*)
WHERE 1 = 2
HAVING 0 < 1;

I don't understand how this works. Can someone explain?

kninwzqo

kninwzqo1#

It may help to look at several similar queries together.

SELECT 'a'              -- One row
SELECT 'b' WHERE 1 = 2  -- Zero rows

SELECT COUNT(*)              -- Result = 1
SELECT COUNT(*) WHERE 1 = 2  -- Result = 0

SELECT COUNT(*) HAVING 0 < 1              -- Result = 1 (passes having criteria)
SELECT COUNT(*) WHERE 1 = 2 HAVING 0 < 1  -- Result = 0 (passes having criteria)

SELECT COUNT(*) HAVING 0 > 1              -- No results (fails having criteria)
SELECT COUNT(*) WHERE 1 = 2 HAVING 0 > 1  -- No results (fails having criteria)

SELECT 'penguins' FROM (VALUES(1),(2)) A(I) -- Two rows containing fixed 'penguins' value
SELECT 'penguins' FROM (VALUES(1),(2)) A(I) HAVING 0 < 1 -- One aggregated row containing fixed 'penguins' value  (passes having criteria)
SELECT 'penguins' FROM (VALUES(1),(2)) A(I) HAVING 0 = 1 -- No results (fails having criteria)

SELECT 'penguins' WHERE 1 = 2 -- Zero rows
SELECT 'penguins' WHERE 1 = 2 HAVING 0 < 1 -- One aggregated row containing fixed value 'penguins'
SELECT 'penguins' WHERE 1 = 2 HAVING 0 = 1 -- No results (fails having criteria)

See this db<>fiddle .

A query with no FROM clause normally returns one row containing the selected values. Adding a WHERE clause may eliminate that one row.

If the select list contains COUNT(*) , the select statement now becomes an aggregation. Lacking a GROUP BY clause, all rows are aggregated into one (even if there are zero rows feeding the group-by). This is properly known as a scalar aggregate. If there was one row before the aggregation, the count will be 1 . If there were no rows feeding the aggregation, the count will be '0' but that count is still part of the result.

The HAVING clause then filters the aggregation results. If the condition is true, the aggregation result is retained in the final result. If the condition is false, the aggregation result is excluded.

As for the SELECT 'penguins' WHERE 1 = 2 HAVING 1 < 0 case, the presence of the HAVING clause also triggers an aggregation (even without GROUP BY ), but turns it into a vector aggregate (which has slightly different semantics). The 'penguins' value then just becomes a fixed value within the aggregated results. Since the HAVING criteria passes, that aggregated row is included in the final result.

All is working as designed.

cu6pst1q

cu6pst1q2#

This is best example

select count(*)
WHERE 1 = 2
HAVING 0 < 1;

Without FROM , it comes down to 1 row - select count(*)

select count(*) -- result: 1. You selected one row

Add WHERE 1 = 2 - no rows returned because 1 <> 2. Hence result is 0.

Also, you can do select count(1) , or select count(33) , without FROM , there are no columns. It creates an output "count" column

Bottom line, this is just an engine behavior. This must be some sort of new ANSI SQL standard (about omitted from and present where ), because Oracle 23c works but prior versions don't. MySQL 8.0 works but 5.5 don't. SQLite 3.39 works but 3.27 don't

相关问题