Maybaygiare.org

Blog Network

Vlad Mihalcea

Última modificación:

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) o TABLESAMPLE 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 de base de datos de canciones

La tabla de base de datos de canciones

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:

song

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ónVALUEdel 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:

canción

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ónNEWIDdevuelve un tipo de datosuniqueidentifier que representa un GUID de 16 bytes. Por lo tanto, cada nuevo valor devuelto por la función NEWID 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:

song

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 randomdevuelve un valor numérico en el intervalo [0, 1) del tipo double 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:

song

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.

Transactions and Concurrency Control eBook

High-Performance Java Persistence rocks!
High-Performance Java Persistence Online Workshop
Hypersistence Optimizer rocks!

Deja una respuesta

Tu dirección de correo electrónico no será publicada.