diff --git a/jOOQ-website/manual/DSL/EXISTS/index.php b/jOOQ-website/manual/DSL/EXISTS/index.php index ba8cefb0ef..3112501559 100644 --- a/jOOQ-website/manual/DSL/EXISTS/index.php +++ b/jOOQ-website/manual/DSL/EXISTS/index.php @@ -45,7 +45,7 @@ Condition notExists(Select<?> query);

When you create such a Condition, it can then be connected to any other condition using AND, OR operators (see also the manual's section on - Conditions). Because of this verbosity, there are also quite a few + Conditions). Because of this verbosity, there are also quite a few convenience methods, where they might be useful. For instance in the org.jooq.Condition itself:

diff --git a/jOOQ-website/manual/DSL/NESTED/index.php b/jOOQ-website/manual/DSL/NESTED/index.php index 95ee000203..e2fc97f80a 100644 --- a/jOOQ-website/manual/DSL/NESTED/index.php +++ b/jOOQ-website/manual/DSL/NESTED/index.php @@ -7,7 +7,9 @@ function printH1() { print "Other types of nested SELECT"; } function getSlogan() { - return ""; + return "Apart from the most common IN and EXISTS clauses that encourage + the use of nested selects, SQL knows a few more syntaxes to make use + of such constructs. "; } function printContent() { global $root; @@ -16,7 +18,128 @@ function printContent() { The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Other types of nested SELECTprevious : next -
+
+

Comparison with single-field SELECT clause

+

If you can ensure that a nested SELECT will only return one Record + with one Field, then you can test for equality. This is how it is done + in SQL:

+ + + + + +
+
+SELECT * 
+  FROM T_BOOK
+ WHERE T_BOOK.AUTHOR_ID = (
+ 		SELECT ID 
+          FROM T_AUTHOR 
+         WHERE LAST_NAME = 'Orwell')
+
+
+create.select()
+      .from(T_BOOK)
+      .where(TBook.AUTHOR_ID.equal(
+            create.select(TAuthor.ID)
+                  .from(T_AUTHOR)
+                  .where(TAuthor.LAST_NAME.equal("Orwell"))));
+
+ +

More examples like the above can be guessed from the + org.jooq.Field API, as documented in the manual's section about + Conditions. For the = operator, the available comparisons are these:

+ +
+Condition equal(Select<?> query);
+Condition equalAny(Select<?> query);
+Condition equalSome(Select<?> query);
+Condition equalAll(Select<?> query);
+ + +

Selecting from a SELECT - SELECT acts as a Table

+

Often, you need to nest a SELECT statement simply because SQL is + limited in power. For instance, if you want to find out which author + has written the most books, then you cannot do this:

+ +
+  SELECT AUTHOR_ID, count(*) books
+    FROM T_BOOK
+GROUP BY AUTHOR_ID
+ORDER BY books DESC
+ +

Instead, you have to do this (or something similar). For jOOQ, this + is an excellent example, combining various SQL features into a single + statement. Here's how to do it:

+ + + + + +
+
+SELECT nested.* FROM (
+      SELECT AUTHOR_ID, count(*) books
+        FROM T_BOOK
+    GROUP BY AUTHOR_ID
+) nested
+ORDER BY nested.books DESC
+
+
+
+
+
+Table<Record> nested = 
+    create.select(TBook.AUTHOR_ID, create.count().as("books"))
+          .from(T_BOOK)
+          .groupBy(TBook.AUTHOR_ID).asTable("nested");
+
+create.select(nested.getFields())
+      .from(nested)
+      .orderBy(nested.getField("books"));
+
+ +

You'll notice how some verbosity seems inevitable when you combine nested SELECT statements with aliasing.

+ +

Selecting a SELECT - SELECT acts as a Field

+

Now SQL is even more powerful than that. You can also have SELECT + statements, wherever you can have Fields. It get's harder and harder + to find good examples, because there is always an easier way to + express the same thing. But why not just count the number of books the + really hard way? :-) But then again, maybe you want to take advantage + of Oracle Scalar Subquery Caching +

+ + + + + +
+
+  SELECT LAST_NAME, (
+      SELECT COUNT(*) 
+       FROM T_BOOK 
+      WHERE T_BOOK.AUTHOR_ID = T_AUTHOR.ID) books
+    FROM T_AUTHOR
+ORDER BY books DESC
+
+
+
+
+
+
+
+// The type of books cannot be inferred from the Select<?>
+Field<Object> books = 
+    create.select(create.count())
+          .from(T_BOOK)
+          .where(TBook.AUTHOR_ID.equal(TAuthor.ID)).asField("books");
+
+create.select(TAuthor.ID, books)
+      .from(T_AUTHOR)
+      .orderBy(books, TAuthor.ID));
+
+
diff --git a/jOOQ-website/src/main/resources/manual.xml b/jOOQ-website/src/main/resources/manual.xml index b7ac854b44..8771f974f4 100644 --- a/jOOQ-website/src/main/resources/manual.xml +++ b/jOOQ-website/src/main/resources/manual.xml @@ -2531,7 +2531,7 @@ Condition notExists(Select<?> query);

When you create such a Condition, it can then be connected to any other condition using AND, OR operators (see also the manual's section on - ). Because of this verbosity, there are also quite a few + ). Because of this verbosity, there are also quite a few convenience methods, where they might be useful. For instance in the itself:

@@ -2576,6 +2576,112 @@ create.select()
Other types of nested SELECT + Apart from the most common IN and EXISTS clauses that encourage + the use of nested selects, SQL knows a few more syntaxes to make use + of such constructs. + +

Comparison with single-field SELECT clause

+

If you can ensure that a nested SELECT will only return one Record + with one Field, then you can test for equality. This is how it is done + in SQL:

+ + + +SELECT * + FROM T_BOOK + WHERE T_BOOK.AUTHOR_ID = ( + SELECT ID + FROM T_AUTHOR + WHERE LAST_NAME = 'Orwell') +create.select() + .from(T_BOOK) + .where(TBook.AUTHOR_ID.equal( + create.select(TAuthor.ID) + .from(T_AUTHOR) + .where(TAuthor.LAST_NAME.equal("Orwell")))); + + +

More examples like the above can be guessed from the + API, as documented in the manual's section about + . For the = operator, the available comparisons are these:

+ + +Condition equal(Select<?> query); +Condition equalAny(Select<?> query); +Condition equalSome(Select<?> query); +Condition equalAll(Select<?> query); + + +

Selecting from a SELECT - SELECT acts as a Table

+

Often, you need to nest a SELECT statement simply because SQL is + limited in power. For instance, if you want to find out which author + has written the most books, then you cannot do this:

+ + + SELECT AUTHOR_ID, count(*) books + FROM T_BOOK +GROUP BY AUTHOR_ID +ORDER BY books DESC + +

Instead, you have to do this (or something similar). For jOOQ, this + is an excellent example, combining various SQL features into a single + statement. Here's how to do it:

+ + + +SELECT nested.* FROM ( + SELECT AUTHOR_ID, count(*) books + FROM T_BOOK + GROUP BY AUTHOR_ID +) nested +ORDER BY nested.books DESC + + + +Table<Record> nested = + create.select(TBook.AUTHOR_ID, create.count().as("books")) + .from(T_BOOK) + .groupBy(TBook.AUTHOR_ID).asTable("nested"); + +create.select(nested.getFields()) + .from(nested) + .orderBy(nested.getField("books")); + + +

You'll notice how some verbosity seems inevitable when you combine nested SELECT statements with aliasing.

+ +

Selecting a SELECT - SELECT acts as a Field

+

Now SQL is even more powerful than that. You can also have SELECT + statements, wherever you can have Fields. It get's harder and harder + to find good examples, because there is always an easier way to + express the same thing. But why not just count the number of books the + really hard way? :-) But then again, maybe you want to take advantage + of Oracle Scalar Subquery Caching

+ + + + SELECT LAST_NAME, ( + SELECT COUNT(*) + FROM T_BOOK + WHERE T_BOOK.AUTHOR_ID = T_AUTHOR.ID) books + FROM T_AUTHOR +ORDER BY books DESC + + + + + +// The type of books cannot be inferred from the Select<?> +Field<Object> books = + create.select(create.count()) + .from(T_BOOK) + .where(TBook.AUTHOR_ID.equal(TAuthor.ID)).asField("books"); + +create.select(TAuthor.ID, books) + .from(T_AUTHOR) + .orderBy(books, TAuthor.ID)); + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Other types of nested SELECTprevious : next