Imagine tener una herramienta que pueda detectar automáticamente problemas de rendimiento JPA e Hibernación. Optimizador de hipersistencia es esa herramienta!
Introducción
En este artículo, veremos cómo podemos ordenar un conjunto de resultados de consulta SQL utilizando una cláusula ORDER BY que toma una función ALEATORIA proporcionada por una función específica de la base de datos.
Este es un truco muy práctico, especialmente cuando desea barajar un conjunto de resultados determinado.
Tenga en cuenta que ordenar un conjunto de resultados grande utilizando una función ALEATORIA puede resultar muy lento, así que asegúrese de hacerlo en conjuntos de resultados pequeños.
Si tiene que barajar un conjunto de resultados grande y limitarlo posteriormente, entonces es mejor usar algo como Oracle
SAMPLE(N)
oTABLESAMPLE
en SQL Server o PostgreSQL en lugar de una función aleatoria en la cláusula ORDER BY.
Tabla de base de datos
Supongamos que estamos desarrollando una aplicación de escritorio de reproductor de música, y tenemos la siguiente tabla song
en nuestra base de datos.
La tabla song
se rellena de la siguiente manera:
id | artist | title |
---|---|---|
1 | Miyagi & Эндшпиль ft. Рем Дигга | I Got Love |
2 | HAIM | Don’t Save Me (Cyril Hahn Remix) |
3 | 2Pac ft. DMX | Aumento De Un Campeón (GalilHD Remix) |
4 | Ed Sheeran & de Pasajeros | No Diggity (Kygo Remix) |
5 | JP Cooper ft. Mali-Koa | Todo este amor |
Usando una función ALEATORIA en la cláusula SQL ORDER BY
Queremos barajar la lista de canciones para que cada nueva lista de reproducción sea diferente de una generada previamente. Cada vez que necesitamos ordenar un conjunto de resultados de consulta SQL dado, tenemos que usar la cláusula ORDER BY.
Sin embargo, para aleatorizar las filas devueltas, necesitamos la cláusula ORDER BY para usar una función u objeto de base de datos que devuelva un valor aleatorio para cada fila contenida en el conjunto de resultados SQL.
Como ya se mencionó, el uso de una función específica de la base de datos que devuelve valores aleatorios es adecuado solo para conjuntos de resultados pequeños, ya que de lo contrario, el rendimiento de la consulta SQL se verá afectado. Afortunadamente, en nuestro caso, la tabla song
representa la lista de reproducción actual de una aplicación de escritorio, por lo que el tamaño del conjunto de resultados es razonable.
Oracle
En Oracle, debe usar la función DBMS_RANDOM.VALUE
, como se ilustra en el siguiente ejemplo:
SELECT artist||' - '||title AS songFROM songORDER BY DBMS_RANDOM.VALUE
Al ejecutar la consulta SQL anterior en Oracle, se obtiene el siguiente conjunto de resultados:
HAIM – Don’t Save Me (Cyril Hahn Remix)
Ed Sheeran & Passenger-No Diggity (Kygo Remix)
Miyagi & Эндшпиль ft. Рем Дигга-I Got Love
JP Cooper ft. Mali-Koa-Todo este Amor
2Pac ft. DMX-Rise Of A Champion (GalilHD Remix)
Observe que las canciones se enumeran en orden aleatorio, gracias a la llamada a la funciónDBMS_RANDOM.VALUE
utilizada por la cláusula ORDER BY.
La función
VALUE
del paqueteDBMS_RANDOM
devuelve un valor numérico en el intervalo [0, 1) con una precisión de 38 dígitos fraccionarios.
SQL Server
En SQL Server, es necesario utilizar la etiqueta NEWID
función, como se ilustra en el siguiente ejemplo:
SELECT CONCAT(CONCAT(artist, ' - '), title) AS songFROM songORDER BY NEWID()
Cuando se ejecuta la consulta SQL anterior de SQL Server, el siguiente conjunto de resultados obtenido es:
Miyagi & Эндшпиль ft. Рем Дигга – I Got Love
HAIM-Don’t Save Me (Cyril Hahn Remix)
2Pac ft. DMX-Rise Of A Champion (GalilHD Remix)
Ed Sheeran &Passenger – No Diggity (Kygo Remix)
JP Cooper ft. Mali-Koa-All This Love
Observe que las canciones se enumeran en orden aleatorio, gracias a la llamada a la funciónNEWID()
utilizada por la cláusula ORDER BY.
La función
NEWID
devuelve un tipo de datosuniqueidentifier
que representa un GUID de 16 bytes. Por lo tanto, cada nuevo valor devuelto por la funciónNEWID
será virtualmente único.
PostgreSQL
En PostgreSQL, debe usar la función random
, como se ilustra en el siguiente ejemplo:
SELECT artist||' - '||title AS songFROM songORDER BY random()
Al ejecutar la consulta SQL anterior en PostgreSQL, se obtiene el siguiente conjunto de resultados:
JP Cooper ft. Mali-Koa-Todo este Amor
2Pac ft. DMX – Rise Of A Champion (GalilHD Remix)
HAIM – Don’t Save Me (Cyril Hahn Remix)
Ed Sheeran & Passenger – No Diggity (Kygo Remix)
Miyagi & Эндшпиль ft. Рем Дигга-I Got Love
Observe que las canciones se enumeran en orden aleatorio, gracias a la llamada a la funciónrandom()
utilizada por la cláusula ORDER BY.
La función
random
devuelve un valor numérico en el intervalo [0, 1) del tipodouble precision
.
MySQL
En MySQL, debe usar la función RAND
, como se ilustra en el siguiente ejemplo:
SELECT CONCAT(CONCAT(artist, ' - '), title) AS songFROM songORDER BY RAND()
Al ejecutar la consulta SQL anterior en MySQL, se obtiene el siguiente conjunto de resultados:
2Pac ft. DMX-Rise Of A Champion (GalilHD Remix)
JP Cooper ft. Mali-Koa-Todo este amor
Miyagi& Эндшпиль ft. Рем Дигга – I Got Love
Ed Sheeran & Passenger – No Diggity (Kygo Remix)
HAIM – Don’t Save Me (Cyril Hahn Remix)
Observe que las canciones se enumeran en orden aleatorio, gracias a la RAND()
llamada a función utilizada por la cláusula ORDER BY.
La función
RAND
devuelve un valor numérico en el intervalo [0, 1) de un tipo de coma flotante.
JPA e Hibernación
Al usar consultas de entidades JPA e Hibernación, puede pasar la función aleatoria a la cláusula ORDER BY, como se ilustra en la siguiente consulta JPQL:
List<Song> songs = entityManager.createQuery( "SELECT s " + "FROM Song s " + "ORDER BY random()", Song.class).getResultList();
La consulta JPQL anterior funcionará perfectamente para PostgreSQL, SQL Server y MySQL dado que las funciones random()
NEWID()
o RAND()
se pasarán por Hibernación tal cual al ORDEN SQL BY.
Para Oracle, dado que la aleatoriedad viene dada por el generador de números DBMS_RANDOM.VALUE
, tendrá que hacer referencia a él como una función SQL (por ejemplo, DBMS_RANDOM.VALUE()
):
List<Song> songs = entityManager.createQuery( "SELECT s " + "FROM Song s " + "ORDER BY DBMS_RANDOM.VALUE()", Song.class).getResultList();
¡Eso es todo!
Talleres en línea
Si disfrutaste de este artículo, ¡apuesto a que te encantará mi próximo Taller en línea de 4 días!
- Taller en línea de Persistencia de Java de alto rendimiento (4 horas x 4 días) entre el 19 y el 22 de abril
Conclusión
Aleatorizar el conjunto de resultados de la consulta SQL es un requisito común, por lo que es útil saber qué función SQL puede usar en la cláusula ORDER BY dependiendo del tipo de base de datos relacional subyacente.