SELECT * FROM Book HAVING NumberOfPages = MAX(NumberOfPages)
The following is written in the standard:
HAVING <search condition>
- Let G be the set consisting of every column referenced by a <column reference> contained in the <group by clause>.
- Each column reference directly contained in the <search condition> shall be one of the following:
- An unambiguous reference to a column that is functionally dependent on G.
- An outer reference.
source
Can somebody explain me, why it should be possible according to the standard?
In MySQL, it perfectly works.
Having can be used without groupby clause,in aggregate function,in that case it behaves like where clause. groupby can be used without having clause with the select statement.
You can also use the having clause with the Transact-SQL extension that allows you to omit the group by clause from a query that includes an aggregate in its select list. These scalar aggregate functions calculate values for the table as a single group, not for groups within the table.
When there is no GROUP BY clause, what does the HAVING clause operate on? Any aggregate functions. The first column in the SELECT clause. The HAVING clause cannot be used without a GROUP BY clause.
While all aggregate functions could be used without the GROUP BY clause, the whole point is to use the GROUP BY clause. That clause serves as the place where you'll define the condition on how to create a group. When the group is created, you'll calculate aggregated values.
Despite the Mimer Validator result, I don't believe yours is valid Standard SQL.
A HAVING
clause without a GROUP BY
clause is valid and (arguably) useful syntax in Standard SQL. Because it operates on the table expression all-at-once as a set, so to speak, it only really makes sense to use aggregate functions. In your example:
Book HAVING NumberOfPages = MAX(NumberOfPages)
is not valid because when considering the whole table, which row does NumberOfPages
refer to? Likewise, it only makes sense to use literal values in the SELECT
clause.
Consider this example, which is valid Standard SQL:
SELECT 'T' AS result FROM Book HAVING MIN(NumberOfPages) < MAX(NumberOfPages);
Despite the absence of the DISTINCT
keyword, the query will never return more than one row. If the HAVING
clause is satisfied then the result will be a single row with a single column containing the value 'T' (indicating we have books with differing numbers of pages), otherwise the result will be the empty set i.e. zero rows with a single column.
I think the reason why the query does not error in mySQL is due to propritary extensions that cause the HAVING
clause to (logically) come into existence after the SELECT
clause (the Standard behaviour is the other way around), coupled with the implicit GROUP BY
clause mentioned in other answers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With