Live data from Hacker News

Having, a less understood SQL clause

smallthingssql.com

51–60 of 83 posts

Re: Having, a less understood SQL clause

#51

Earlier quoted context omitted.

I had never heard of GROUP BY CUBE either! It looks like it's part of a family of special GROUP BY operators—GROUPING SETS, CUBE, and ROLLUP—that basically issue the same query multiple times with different GROUP BY expressions and UNION the results together. Using GROUP BY CUBE(a, b, c, ...) creates GROUP BY expressions for every element in the power set of {a, b, c, ...}, so GROUP BY CUBE(a, b) does separate GROUP…

I would gladly buy a book of "SQL Recipes" ranging from beginner-level to advanced stuff that uses features like this, ideally with coverage of at least a few popular database systems, but at minimum Postgres. Is there such a book?

In fact, Yugabyte is giving it away for free - https://downloads.yugabyte.com/marketing-assets/O-Reilly-SQL...

Re: Having, a less understood SQL clause

#52
post #19

Having is the where-clause for Group By. It's easier to understand by thinking the SQL query as a pipeline. Stage 1: From returns the whole world of rows. Stage 2: Where filters down to the desired set of rows. Stage 3: Group By aggregates the filtered rows. Stage 4: Having filters again on the aggregated result. Stage 5: Select picks out the columns.

What I never understood is why HAVING and WHERE are different clauses. AFAIU, there are no cases where both could be used, so why can’t one simply use WHERE after a GROUP BY? (I know that I am probably missing some important technical points, I would like to learn about them)

There's plenty of cases - remove the people who have attribute, then aggregate them, then filter the aggregate.

Find me the list of non-deleted users who have more than 50 dollars worth of transactions in the transaction table.

Technically you can always subquery and use a where instead of a having but its nice to ... have.

Re: Having, a less understood SQL clause

#53
post #26
post #5

Having is less understood? After 20+ years of SQL usage (as an ordinary dev, not business/reporting/heavy SQL dev), I learned about `group by cube` from this article... "group by cube/coalesce" is much more complicated thing in this article than "having" (that could be explained as where but for group by)

Exactly the same for me. It makes me think I need to start reading the TSQL documentation cover to cover.

Not a huge fan of Microsoft but the TSQL documentation is solid. If you're not using CROSS APPLY to tear apart things and put them back together you've not lived.

Re: Having, a less understood SQL clause

#54

Earlier quoted context omitted.

I had never heard of GROUP BY CUBE either! It looks like it's part of a family of special GROUP BY operators—GROUPING SETS, CUBE, and ROLLUP—that basically issue the same query multiple times with different GROUP BY expressions and UNION the results together. Using GROUP BY CUBE(a, b, c, ...) creates GROUP BY expressions for every element in the power set of {a, b, c, ...}, so GROUP BY CUBE(a, b) does separate GROUP…

I would gladly buy a book of "SQL Recipes" ranging from beginner-level to advanced stuff that uses features like this, ideally with coverage of at least a few popular database systems, but at minimum Postgres. Is there such a book?

Joe Celko has a number of SQL for Smarties books I've been meaning to look through.

Re: Having, a less understood SQL clause

#55
post #5

Having is less understood? After 20+ years of SQL usage (as an ordinary dev, not business/reporting/heavy SQL dev), I learned about `group by cube` from this article... "group by cube/coalesce" is much more complicated thing in this article than "having" (that could be explained as where but for group by)

I had never heard of GROUP BY CUBE either! It looks like it's part of a family of special GROUP BY operators—GROUPING SETS, CUBE, and ROLLUP—that basically issue the same query multiple times with different GROUP BY expressions and UNION the results together. Using GROUP BY CUBE(a, b, c, ...) creates GROUP BY expressions for every element in the power set of {a, b, c, ...}, so GROUP BY CUBE(a, b) does separate GROUP…

Yes, PostgreSQL (9 and later), SQL Server (2008 and later), Oracle, SQL Anywhere and DB2 support grouping sets. All had it for longer than a decade.

Some also support the MySQL/MariaDB with rollup syntax introduced in 2018.

Re: Having, a less understood SQL clause

#56

Earlier quoted context omitted.

I think left join is a bad name. Probably something like OPTIONAL JOIN or TRY JOIN would be more obvious. Of course the problem is then what do you call a right join? REVERSE OPTIONAL JOIN? But that is getting pretty confusing now. But maybe worth it because in my experience left is far more common.

It's best to pretend that RIGHT JOIN doesn't exist, imnsho. For one thing, in SQLite, it doesn't. Which is a weak argument for not using it on supported systems. The other weak argument is that a RIGHT JOIN is just the b, a version of a LEFT JOIN a, b. When you add them up it's an extra concept, SQL execution flow is already somewhat unintuitive, and a policy of using one of the two ways of saying "everything from a…

> For one thing, in SQLite, it doesn't.

It does now, since the latest release 3.39, along with full join.

Re: Having, a less understood SQL clause

#57
post #49

Earlier quoted context omitted.

What I never understood is why HAVING and WHERE are different clauses. AFAIU, there are no cases where both could be used, so why can’t one simply use WHERE after a GROUP BY? (I know that I am probably missing some important technical points, I would like to learn about them)

select product , sum(price) as price from table where price 10000 You can refer to the aliased price column before or after aggregation using where or having. Depending on the sql engine.

I didn’t know one could still refer to the value before aggregation after it is aliased.

Is there an implicit group by in this query?

Re: Having, a less understood SQL clause

#58
post #19

Having is the where-clause for Group By. It's easier to understand by thinking the SQL query as a pipeline. Stage 1: From returns the whole world of rows. Stage 2: Where filters down to the desired set of rows. Stage 3: Group By aggregates the filtered rows. Stage 4: Having filters again on the aggregated result. Stage 5: Select picks out the columns.

What I never understood is why HAVING and WHERE are different clauses. AFAIU, there are no cases where both could be used, so why can’t one simply use WHERE after a GROUP BY? (I know that I am probably missing some important technical points, I would like to learn about them)

It doesn't improve the power of SQL, it's just syntactic sugar. Because of how the SQL syntax works, you'd have to do something like:

   WITH A AS (
        SELECT x, sum(y) AS z
          FROM SomeTable
      GROUP BY x
   )

   SELECT * FROM A WHERE z > 10
With an HAVING clause you can instead just tuck it after the GROUP BY clause.

Also, although it's not an issue these days given how good query planners are (any decent engine will produce exactly the same query plan with a subquery or an having clause, it's indexes that fuck up stuff), but you're signaling that the filter happens "at the end".

It's like having both "while" and "for" in a programming language. Technically you don't need it, but it's for humans and not for compilers.

Re: Having, a less understood SQL clause

#59

Earlier quoted context omitted.

I would gladly buy a book of "SQL Recipes" ranging from beginner-level to advanced stuff that uses features like this, ideally with coverage of at least a few popular database systems, but at minimum Postgres. Is there such a book?

Joe Celko has a number of SQL for Smarties books I've been meaning to look through.

These are phenomenonal books. Your understanding of sql as both a language and as a tool will be transformed.

A bit dated in places but that also is helpful as you learn how a technique works instead of just relying on a vendor specific extension

Re: Having, a less understood SQL clause

#60
post #49

Earlier quoted context omitted.

What I never understood is why HAVING and WHERE are different clauses. AFAIU, there are no cases where both could be used, so why can’t one simply use WHERE after a GROUP BY? (I know that I am probably missing some important technical points, I would like to learn about them)

select product , sum(price) as price from table where price 10000 You can refer to the aliased price column before or after aggregation using where or having. Depending on the sql engine.

This is non-standard and highly dependent on the sql engine. If you believe in portability, your where clauses should (sadly) use the long form.

If that's not a requirement, this approach can add some clarity

Post reply on HN