On Thursday, 28 September 2023 at 14:03:32 UTC+2 Lukas Eder wrote: Hi Yafl,
The UNION ALL operator looks as though it belongs to the SELECT statement, and jOOQ certainly makes it look so as well. But it doesn't really. It creates a new kind of statement that wraps 2 subqueries. Think of it this way: UnionAll(Select1, Select2) Ah, that makes sense! If I think about it that way, I also see more clearly why the aliases of the selects cannot be referenced anymore – because they are defined in an inner scope, whereas ORDER BY sits in the outer scope. I don't know if that's what actually happens (see below too), because I learned now that SQL can be very involved when it comes to (logical) execution order and what's accessible when, but it does help to think about it this way. :) Now that query continues to project things, and by convention (there are exceptions, e.g. this bug in Oracle: https://stackoverflow.com/q/25387951/521799), the names of the projected columns corresponds to the (unqualified!) column names from the first subquery. Now, some RDBMS allow for referencing those columns by name in the UNION's ORDER BY clause, others don't. jOOQ has a few open issues in this area. Some things may be expected to work (e.g. ORDER BY <column index>). In your case, I don't think jOOQ should do any magic such as unnesting the nested column again, just because it happens to be there. You could have any other column called "first_name", which is something entirely different (e.g. any expression) and then why would jOOQ prefer to unnest the nested column. I agree, I didn't expect jOOQ to implement magic here. I merely posted it to gain a better understanding of what's happening. In SQL, the column that you've nested ceases to exist outside of the UNION operator because you've nested it. This is different without a UNION (and without DISTINCT), because the column names that are not projected with SELECT may still be accessed by ORDER BY in most "reasonable" dialects. Though again, there might be exceptions, e.g.: https://github.com/trinodb/trino/issues/18726 I mentioned DISTINCT, because that creates a similar situation like UNION. I've described in in this blog post: https://blog.jooq.org/how-sql-distinct-and-order-by-are-related/ Ah, so is this the reason why the version without UNION works? Because it is accessing the table name and not the alias? Here my thinking was wrong. Good to know! In fact, separating the names of different things, I can validate this – the following doesn't work: select row (p.id, p.first_name, p.last_name, ...) as a, book.title from author as p join book on p.id = book.author_id where ... order by a.first_name whereas this does: select row (p.id, p.first_name, p.last_name, ...) as a, book.title from author as p join book on p.id = book.author_id where ... order by p.first_name The first one gives a «ERROR: Missing FROM-clause entry for table "a"». Is that because table aliases need to be defined in the from clause always? Because in the logical execution order, ORDER BY comes after SELECT, so I could imagine that it could theoretically access an alias defined in the SELECT statement. On the other hand, the entries in the column "a" are just strings of the form "(value1,value2,...)", not actual tables, so there's no way to access a column in there. If it was a table, it might be possible. You showed the difference it very well in this blog post with the DBeaver screenshots: https://blog.jooq.org/projecting-type-safe-nested-tablerecords-with-jooq-3-17/ So would the query work with a nested table in the select? Or would it still not work, because ORDER BY cannot access aliases defined in SELECT? I wanted to test this, but I cannot reproduce the nested result anymore, even with postgres in DBeaver (as described in the mentioned blog post). It always gives me rows, also with just plain simple "SELECT Table FROM Table". Don't know why. I'm pretty sure it worked at least once before. Although I read multiple times on your blog about the logical execution order of the SQL clauses and the subtleties of SQL, the order in which SQL is written still confuses me and I somehow expect references from the select to be accessible elsewhere. I'm thinking about starting to rewrite my SQL statement in the logical execution order to spot errors more easily when an error occurs. But then still, if aliases from the SELECT clause are not accessible in the ORDER BY clause, the execution order cannot be the reason for that. Sigh. -- You received this message because you are subscribed to the Google Groups "jOOQ User Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to jooq-user+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/jooq-user/a3ee156a-6518-41ed-b6fd-d2c56a0a908en%40googlegroups.com.