ЗАКАЗАТЬ по состоянию - PullRequest
2 голосов
/ 03 марта 2010

Я хотел бы получить упорядоченный результат запроса, но мне нужно, чтобы перед списком были определенные строки. Примерно здесь, в переполнении стека, в списке ответов правильный ответ всегда первый.

Предполагается, что я должен иметь строки с идентификаторами 1,2,3 в качестве заголовка, остальные отсортированы по полю даты, возможно ли сделать что-то вроде:

SELECT * FROM foo ORDER BY id IN (1,2,3), created_date

Если нет, то что эффективнее? Будет много строк!

SELECT *, 0 AS head FROM foo WHERE id IN (1,2,3) 
UNION
SELECT *, 1 AS head FROM foo WHERE id NOT IN (1,2,3)
ORDER BY head, created_date

или

SELECT *, IF(id IN (1,2,3), 0, 1) AS head
ORDER BY head, created_date

(сейчас я использую MySQL, но меня интересует любое другое решение SQL.)

Ответы [ 2 ]

3 голосов
/ 03 марта 2010

UNION означает UNIST DISTINCT, и это относительно медленно, поскольку он будет проверять дубликаты, даже если их не будет. Вы хотите СОЮЗ ВСЕХ:

SELECT *, 0 AS head FROM foo WHERE id IN (1,2,3) 
UNION ALL
SELECT *, 1 AS head FROM foo WHERE id NOT IN (1,2,3)
ORDER BY head, created_date

Я бы предположил, что после этого изменения между запросами не будет большой разницы в производительности. Лучший способ убедиться в этом - это измерить.

2 голосов
/ 03 марта 2010

Ваш первый пример выглядит почти для меня.

SELECT * FROM foo ORDER BY id IN (1,2,3) DESC, created_date ASC

Добавлено DESC, потому что id IN (1,2,3) возвращает 1, если истина, или 0, если ложь. 1 > 0, поэтому упорядочение по убыванию дает желаемый результат.

Добавлен ASC, потому что мне нравится быть явным.

Основываясь на ваших более поздних примерах, я думаю, что вам не хватает того, что, хотя он содержит пробелы, field IN (list) является единственным оператором, который возвращает 0 или 1. IF(id IN (1,2,3), 0, 1) по своей сути избыточен.

Таким образом, вам не нужно использовать сортировку UNION или вручную, поскольку MySQL делает это проще, чем вы даже себе представляете:)

...