samedi 8 août 2015

SQL query optimization: take entry with a certain condition, or random entry otherwise

I want to create an SQL query for SQLite 3 that takes the first value (lowest ID) where a certain condition is met. If there is no such entry, I want to get a random row. So assuming there is at least one entry in the table, I always want exactly one row returned.

Consider this example table:

CREATE TABLE `jukebox` (
    `id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    `title` TEXT NOT NULL,
    `lastplayed`    INTEGER NOT NULL DEFAULT '0'
);

For this example, I want to retrieve the first song that was not played (lastplayed = 0). If there is no such song, I'd like to return a random row from the table.

This is what I created so far. It is an ugly monster, and I'm pretty sure it's not very performant.

SELECT * FROM (
    SELECT * FROM (SELECT * FROM jukebox WHERE lastplayed = 0 ORDER BY id DESC)
    UNION
    SELECT * FROM (SELECT * FROM jukebox ORDER BY RANDOM() LIMIT 1)
) LIMIT 1

I know I can omit the ORDER BY id DESC part. I just left it there so it is clear what result I am expecting.

Strangely, I cannot remove the LIMIT 1 after RANDOM(), as I won't get a random result then.

Is there any way to optimize this query?

Aucun commentaire:

Enregistrer un commentaire