Возвращает true, если все значения столбцов true
есть ли более быстрый способ в PostgreSQL по существу сделать if на нескольких строках?
скажем у меня есть таблица
ticket | row | archived
1 | 1 | true
1 | 2 | true
1 | 3 | true
2 | 1 | false
2 | 2 | true
есть ли способ сделать оператор if через столбец, где ticket = ? Так что, где ticket = 1 было бы верно, потому что
true && true && true = true
и где ticket = 2 будет ложным, потому что
false && true = false
или я должен просто палка с
SELECT ( (SELECT COUNT(*) FROM table WHERE ticket = 1)
= (SELECT COUNT(*) FROM table WHERE ticket = 1 AND archived = true) )
3 ответов
Агрегатная функция bool_and()
просто, коротко, ясно.
SELECT bool_and(archived)
FROM tbl
WHERE ticket = 1;
я цитирую руководство здесь:
true if all input values are true, otherwise false
выражение вложенного запроса EXISTS
- как @Mike при условии
быстрее. Но вы должны дополнительно проверить, есть ли строки с ticket = 1
существуют вообще, или вы получите неправильные результаты для несуществующих билеты:
SELECT EXISTS (SELECT 1 FROM tbl WHERE ticket=1)
AND NOT
EXISTS (SELECT 1 FROM tbl WHERE ticket=1 AND archived = FALSE);
индексы
обе формы могут и будут использовать индекс, как:
CREATE index tbl_ticket_idx ON tbl (ticket);
.. что делает оба быстро, но EXISTS
запрос быстрее, потому что эта форма может остановить сканирование, как только будет найдена первая соответствующая строка. Вряд ли существует какая-либо разница между двумя запросами с несколькими строками на билет, но существенный разница для многих строк за билет.
использовать сканирование в pg 9.2 вам понадобится многостолбцовый индекс вида:
CREATE index tbl_ticket_archived_idx ON tbl (ticket, archived);
это лучше на в любом случае большинство случаев и любая версия PostgreSQL. Из-за выравнивание данных добавление boolean
до integer
в индексе не заставит индекс расти вообще. Добавленное преимущество для едва ли любой цены.
однако индексированные столбцы предотвращают горячее (только куча Кортеж) обновления. Скажи UPDATE
изменяется только столбец archived
. Если столбец не используется каким-либо индексом (каким-либо образом), строка может быть обновлена. В противном случае, этот ярлык не может быть принят. Я написал больше о горячих обновлениях в этом соответствующем ответе.
Итак, как всегда, все зависит от вашей точной нагрузки.
как насчет чего-то вроде:
select not exists (select 1 from table where ticket=1 and not archived)
Я думаю, что это может быть выгодно по сравнению с сравнением подсчетов, как count
может или не может использовать индекс и в самом деле все, что вам нужно знать, если любой FALSE
строки существуют для этого билета. Я думаю, просто создав частичный индекс на ticket
может быть невероятно быстрым.