#sql #ansi-sql
#sql #ansi-sql
Вопрос:
Существует ли кросс-база данных (по крайней мере, SQL Server, Oracle, Postgre, MySQL, SQLite) способ сделать то, что я бы сделал в T-SQL, используя
SELECT 1 WHERE EXISTS (SELECT * FROM Foo WHERE Bar = 'Quux')
Кажется, что это недопустимый синтаксис ANSI SQL, потому что в нем нет предложения FROM . В настоящее время я использую COUNT (*) для этого, но я не думаю, что это оптимально.
Ответ №1:
Подзапрос не нужен — используйте:
SELECT DISTINCT
1
FROM Foo
WHERE Bar = 'Quux'
Более сложная версия, использующая агрегаты и выражение CASE:
SELECT CASE
WHEN COUNT(*) >= 1 THEN 1
ELSE 0
END
FROM Foo
WHERE Bar = 'Quux'
Комментарии:
1. Интересно, почему бы не использовать limit вместо distinct? Разве это не совместимо с ABSI? ВЫБЕРИТЕ 1 Из Foo, ГДЕ Bar = ‘Quux’ LIMIT 1;
2. @andrii К сожалению, LIMIT не совместим с ANSI. Начиная с SQL2008, у нас есть преимущество «ВЫБОРКИ ТОЛЬКО ПЕРВЫХ n СТРОК» и оконных агрегатных функций, но их поддерживают только несколько ядер баз данных. Также LIMIT сильно отличается от DISTINCT. Мы знаем, что здесь все кортежи у нас одинаковые, следовательно, возвращаем результат в одну строку с DISTINCT. Здесь нет необходимости искусственно прерывать результирующий набор.
Ответ №2:
Немного обманываю, но это должно сработать, и DISTINCT 1 FROM Foo
должно быть тривиально оптимизировано всеми, кроме самой тупой из СУБД!
SELECT DISTINCT 1 FROM Foo WHERE EXISTS (SELECT * FROM Foo WHERE Bar = 'Quux')
Ответ №3:
Просто используйте COUNT, пока вам не понадобится иное. Предполагая хорошую избирательность по строке и индексу, это не будет иметь большого значения, но будет гораздо более читаемым
SELECT COUNT(Bar) FROM Foo WHERE Bar = 'Quux'
Конечно, вы обменяете оптимизацию на переносимость, поэтому в этом случае используйте COUNT
Комментарии:
1. Я работаю над библиотекой общего назначения, поэтому мне нужно наилучшее сочетание оптимального и переносимого. И печенье! 🙂