Getting Top 1 Values Per Group in Oracle

I've blogged about generic ways of getting top 1 or top n per category queries before on this blog. An Oracle specific version in that post used the arcane KEEP syntax: SELECT max(actor_id) KEEP (DENSE_RANK FIRST ORDER BY c DESC, actor_id), max(first_name) KEEP (DENSE_RANK FIRST ORDER BY c DESC, actor_id), max(last_name) KEEP (DENSE_RANK FIRST ORDER … Continue reading Getting Top 1 Values Per Group in Oracle

An Efficient Way to Check for Existence of Multiple Values in SQL

In a previous blog post, we've advertised the use of SQL EXISTS rather than COUNT(*) to check for existence of a value in SQL. I.e. to check if in the Sakila database, actors called WAHLBERG have played in any films, instead of: SELECT count(*) FROM actor a JOIN film_actor fa USING (actor_id) WHERE a.last_name = … Continue reading An Efficient Way to Check for Existence of Multiple Values in SQL

A Hidden Benefit of Implicit Joins: Join Elimination

One of jOOQ's key features so far has always been to render pretty much exactly the SQL that users expect, without any surprises - unless some emulation is required to make a query work, of course. This means that while join elimination is a powerful feature of many RDBMS, it isn't part of jOOQ's feature … Continue reading A Hidden Benefit of Implicit Joins: Join Elimination

jOOQ 3.19’s new Explicit and Implicit to-many path joins

jOOQ 3.19 finally delivers on a set of features that will greatly simplify your queries further, after jOOQ 3.11 introduced implicit to-one joins: Explicit path joins To-many path joins Implicit join path correlation What are these features? Many ORMs (e.g. JPA, Doctrine, jOOQ 3.11 and others) support "path joins" (they may have different names for … Continue reading jOOQ 3.19’s new Explicit and Implicit to-many path joins

Workaround for MySQL’s “can’t specify target table for update in FROM clause” Error

In MySQL, you cannot do this: create table t (i int primary key, j int); insert into t values (1, 1); update t set j = (select max(j) from t) + 1; The UPDATE statement will raise an error as follows: SQL Error [1093] [HY000]: You can't specify target table 't' for update in FROM … Continue reading Workaround for MySQL’s “can’t specify target table for update in FROM clause” Error

Maven Coordinates of the most popular JDBC Drivers

Do you need to add a JDBC driver to your application, and don't know its Maven coordinates? This blog post lists the most popular drivers from the jOOQ integration tests. Look up the latest versions directly on https://central.sonatype.com/ with parameters g:groupId a:artifactId, for example, the H2 database and driver: https://central.sonatype.com/search?q=g%3Acom.h2database+a%3Ah2 The list only includes drivers … Continue reading Maven Coordinates of the most popular JDBC Drivers

How to Turn a List of Flat Elements into a Hierarchy in Java, SQL, or jOOQ

Occasionally, you want to write a SQL query and fetch a hierarchy of data, whose flat representation may look like this: SELECT id, parent_id, label FROM t_directory; The result might be: |id |parent_id|label | |---|---------|-------------------| |1 | |C: | |2 |1 |eclipse | |3 |2 |configuration | |4 |2 |dropins | |5 |2 |features | … Continue reading How to Turn a List of Flat Elements into a Hierarchy in Java, SQL, or jOOQ

How to Write a Derived Table in jOOQ

One of the more frequent questions about jOOQ is how to write a derived table (or a CTE). The jOOQ manual shows a simple example of a derived table: In SQL: SELECT nested.* FROM ( SELECT AUTHOR_ID, count(*) books FROM BOOK GROUP BY AUTHOR_ID ) nested ORDER BY nested.books DESC In jOOQ: // Declare the … Continue reading How to Write a Derived Table in jOOQ

The Performance Impact of SQL’s FILTER Clause

I've found an interesting question on Twitter, recently. Is there any performance impact of using FILTER in SQL (PostgreSQL, specifically), or is it just syntax sugar for a CASE expression in an aggregate function? https://twitter.com/Ivan73965858/status/1622487080088600576 As a quick reminder, FILTER is an awesome standard SQL extension to filter out values before aggregating them in SQL. … Continue reading The Performance Impact of SQL’s FILTER Clause

Emulating Window Functions in MySQL 5.7

One of MySQL 8's biggest improvements is the support of window functions. As I always said in conferences, there's SQL before window functions and SQL after window functions. Once you start using them, you'll use them everywhere. Some of you poor souls are unfortunate enough to be stuck on MySQL 5.7, either of your own … Continue reading Emulating Window Functions in MySQL 5.7