Проще, быстрее:
SELECT * FROM COALESCE(
(SELECT s FROM statuses s WHERE parent_id = 9 LIMIT 1)
,(SELECT s FROM statuses s WHERE id = 9 LIMIT 1)
)
Если ни один из идентификаторов не существует, этот запрос возвращает строку типа statuses
, заполненную NULL
значениями, в то время как другие решения здесь пока возвращают без строки . Потому что это то, что происходит, когда вы звоните
SELECT * FROM NULL::statuses
.
Объяснение
COALESCE
не может работать с rows
per se, подзапрос вместо переменной должен возвращать только один столбец. Если вы попробуете:
<strike>SELECT COALESCE(
(SELECT * FROM statuses WHERE parent_id = 9 LIMIT 1)
,(SELECT * FROM statuses WHERE id = 9 LIMIT 1)
)
</strike>
Вы получаете
ОШИБКА: подзапрос должен возвращать только один столбец
Однако для каждой таблицы в PostgreSQL существует составной тип с таким же именем. Вы можете сделать так, чтобы подзапросы возвращали всю строку как составной тип и впоследствии расширяли тип. Вот что делает запрос.
Я выполнил быстрый тест с похожей реальной таблицей из 70 тыс. Строк в PostgreSQL 9.1.4, оба индекса с уникальным идентификатором проиндексированы . Я проверил все три случая: parent_id
существует, id
существует, ни один не существует. Этот запрос немного быстрее, чем другое решение здесь. Я также попробовал фиксированный эквивалент неправильного ответа @ Parkyprg и упрощенную версию того, что @Endy и @Andomar опубликовали:
SELECT *
FROM statuses
WHERE parent_id = 9 OR id = 9
ORDER BY (id <> 9);
.. что может быть быстрее для таблиц без индексов.