I came across this puzzle in the comments here
CREATE TABLE r (b INT);
SELECT 1 FROM r HAVING 1=1;
SQL Server and PostgreSQL return 1 row.
MySQL and Oracle return zero rows.
Which is correct? Or are both equally valid?
|
I came across this puzzle in the comments here
SQL Server and PostgreSQL return 1 row. MySQL and Oracle return zero rows. Which is correct? Or are both equally valid? |
|||
| show 4 more comments |
|
Per the standard:
means
Citation ISO/IEC 9075-2:2011 7.10 Syntax Rule 1 (Part of the definition of the HAVING clause):
Ok so that much is pretty clear. Assertion: Now
is equivlent to
Citation ISO/IEC 9075-2:2011 7.10 General Rule 1:
Logic: Since the search condition is always true, the result is The following is an excerpt from the General Rules of 7.9 (the definition of the GROUP BY CLAUSE)
Thus we can conclude that
results in a grouped table, consisting of one group, with zero rows (since R is empty). An excerpt from the General Rules of 7.12, which defines a Query Specification (a.k.a a SELECT statement):
Therefore since the table has one group, it must have one result row. Thus
should return a 1 row result set. Q.E.D. |
|||||||||
|
|
When there is a
... then
... which should group all rows of the table into one group (even if the table has no rows at all - it's still one group of 0 rows) and return 1 row. The From a different angle, how many rows should a query like this return?
One, zero or "zero or one, depending on if the table is empty or not"? I think one row, no matter how many rows |
|||||||||||||
|
|
From what I see, it looks like SQLServer and PostgerSQL don't bother looking into table at all:
also returns just one row. Even though SQLServer docs says
that is not true in this case - Oracle and Mysql behaviour seems more logical and correct to me... |
|||||||
|
SELECT COUNT(*) FROM r;returns 1 row (with0), whileSELECT COUNT(*) FROM r GROUP BY ();returns no rows. – ypercube Jan 29 at 17:35SELECT 1 WHERE 1=0 HAVING 1=1;. SQL Server and PostgreSQL still return one row. Oracle wants FROM DUAL and returns no rows. MySQL doesn't compile neither with FROM DUAL nor without it. – Andriy M Jan 29 at 19:04SELECT 1 AS t FROM (SELECT 1) tmp WHERE 1=0 HAVING 1=1;1-row-no-dual and returns 0 rows. – ypercube Jan 29 at 21:33GROUP BY. Without intervention from Dr Emmett Brown, the behaviour of any particular product is unlikely to change (for backward-compatibility reasons). SQL Server 2008 onward implement theGROUP BY ()syntax and rules. – Paul White Jan 30 at 11:23HAVINGdifferently): SQl-fiddle 2: HAVING makes things different – ypercube Jan 30 at 13:02