Cómo escribir una tabla derivada en jOOQ - Java, SQL y jOOQ.

Cómo escribir una tabla derivada en jOOQ - Java, SQL y jOOQ.

Una de las preguntas más frecuentes sobre jOOQ es cómo escribir una tabla derivada (o CTE). El manual de jOOQ muestra un ejemplo simple de una tabla derivada:

En SQL:

SELECT nested.*
FROM (
  SELECT AUTHOR_ID, count(*) books
  FROM BOOK
  GROUP BY AUTHOR_ID
) nested
ORDER BY nested.books DESC

En jOOQ:

// Declare the derived table up front:
Table<?> nested =
    select(BOOK.AUTHOR_ID, count().as("books"))
    .from(BOOK)
    .groupBy(BOOK.AUTHOR_ID).asTable("nested");

// Then use it in SQL:
ctx.select(nested.fields())
   .from(nested)
   .orderBy(nested.field("books"))
   .fetch();

Y eso es todo. La pregunta suele surgir del hecho de que hay una sorprendente falta de seguridad de tipos cuando se trabaja con tablas derivadas (o CTE, que no son tan diferentes). Tienes que entender dos cosas:

  1. A diferencia de SQL, el lenguaje Java puede hacer referencia a un objeto que aún no ha sido declarado, léxicamente, por lo que debemos declarar la tabla derivada. Antes Al usarlo.
  2. A diferencia del código generado a partir del catálogo, una tabla derivada es solo una expresión y realmente no hay una buena forma de agregar atributos a esa expresión, según la estructura de la expresión, al menos no en Java. Esto significa que las columnas de una tabla derivada no se pueden desreferenciar de forma segura. Sin embargo, puede reutilizar expresiones, como se muestra a continuación:
// Declare a field expression up front:
Field<Integer> count = count().as("books");

// Then use it in the derived table:
Table<?> nested =
    select(BOOK.AUTHOR_ID, count)
    .from(BOOK)
    .groupBy(BOOK.AUTHOR_ID).asTable("nested");

// And use it as well in the outer query, when dereferencing a column:
ctx.select(nested.fields())
   .from(nested)
   .orderBy(nested.field(count))
   .fetch();
Índice
  1. ¿Realmente necesitabas la tabla derivada?
  2. Conclusión
    1. Así:

¿Realmente necesitabas la tabla derivada?

A menudo, cuando respondo tales preguntas en Stack Overflow o en otro lugar, se vuelve obvio que la tabla derivada no era necesaria en primer lugar. De hecho, ¡este mismo ejemplo del manual de jOOQ no necesitaba una tabla derivada! La consulta SQL se puede simplificar a esto:

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

Nada se pierde con esta simplificación. Ver cuándo puede tener lugar la simplificación puede requerir algo de práctica. Siempre es bueno tener en cuenta el orden lógico de las operaciones en SQL, para garantizar que la consulta resultante sea equivalente. Pero cuando lo hace, es mucho más fácil traducirlo a jOOQ, porque ahora podemos usar el código generado nuevamente, en todas partes, y ya no tenemos que depender de la desreferenciación menos segura de columnas de tablas derivadas. . Aquí está el equivalente de jOOQ:

// We can still assign expressions to local variables
Field<Integer> count = count().as("books");

// And then use them in the query:
ctx.select(BOOK.AUTHOR_ID, count)
   .from(BOOK)
   .groupBy(BOOK.AUTHOR_ID)
   .orderBy(count)
   .fetch();

Conclusión

Entonces, cuando está trabajando con jOOQ y su consulta es lo suficientemente simple, entonces su pregunta de

¿Cómo escribir una tabla derivada en jOOQ?

Se puede cambiar a:

¿Necesito una tabla derivada en primer lugar?

De esta manera puede mejorar tanto su consulta jOOQ como su consulta SQL

Si quieres conocer otros artículos parecidos a Cómo escribir una tabla derivada en jOOQ - Java, SQL y jOOQ. puedes visitar la categoría Código.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Esta página web utiliza cookies para analizar de forma anónima y estadística el uso que haces de la web, mejorar los contenidos y tu experiencia de navegación. Para más información accede a la Política de Cookies . Ver mas