Как смоделировать наибольшее () в Sybase ASE?
-
27-10-2019 - |
Вопрос
У большинства баз данных есть что -то вроде GREATEST
функция, которая может быть полезна несколько раз. По крайней мере, эти базы данных не имеют такой функции:
- дерби
- SQL Server
- Sybase Ase
- Sybase SQL в любом месте
Для SQL Server и Sybase SQL в любом месте функция может быть смоделирована с помощью подразделений и UNION ALL
, как можно увидеть в Этот вопрос здесь. Анкет Пример:
-- SELECT GREATEST(field1, field2, field3) FROM my_table
SELECT (SELECT MAX(c) FROM
(SELECT my_table.field1 AS c UNION ALL
SELECT my_table.field2 UNION ALL
SELECT my_table.field3) T) AS greatest
FROM my_table
Но это не работает в Sybase ASE. Видимо, у подводов нет доступа к внешнему запросу my_table
ссылка. Ошибка, которую я получаю
Префикс столбца «my_table» не соответствует имени таблицы или имени псевдонима, используемого в запросе. Либо таблица не указана в предложении FROW, либо имеет имя корреляции, которое должно использоваться вместо этого
Обратите внимание, что эта проблема не появляется в Sybase SQL. Есть идеи, что здесь не так и как я мог бы переписать запрос?
Я хотел бы избежать
- Сохраненные функции, так как у меня может не быть необходимых грантов для их создания
- Длинный
CASE
выражения, как длина выражения комбинированной перестановки всех сравнений, необходимых с вложеннымиCASE
выражения, по крайней мере,O(n^2)
когдаn
это количество параметров дляGREATEST
Решение
Насколько я понимаю, логика (игнорируя нулевые)
SELECT CASE
WHEN field1 >= field2
AND field1 >= field3
THEN field1
WHEN field2 >= field3
THEN field2
ELSE field3
END AS greatest
FROM my_table;
... но должен вернуть нуль только тогда, когда все значения являются нулевыми.
Я думаю, что это скорее то, как я хотел бы иметь возможность делать что -то (хотя Sybase ASE не поддерживает общие выражения таблицы):
WITH my_table
AS
(
SELECT *
FROM (
VALUES ('A', 1, 2, 3),
('B', 2, 3, 1),
('C', 3, 1, 2),
('D', NULL, 2, 3),
('E', NULL, NULL, 3),
('F', NULL, 3, NULL),
('G', 1, NULL, 3),
('H', 1, 3, NULL),
('X', NULL, NULL, NULL)
) AS T (ID, field1, field2, field3)
),
T1
AS
(
SELECT ID, field1 AS field_n
FROM my_table
UNION
SELECT ID, field2 AS field_n
FROM my_table
UNION
SELECT ID, field3 AS field_n
FROM my_table
)
SELECT ID, MAX(field_n) AS greatest
FROM T1
GROUP
BY ID;
Другие советы
В этом случае я добавлю один дополнительный CASE
.
SELECT
CASE WHEN field1 IS NOT NULL
AND field2 IS NOT NULL
AND field3 IS NOT NULL THEN
CASE WHEN field1 >= field2
AND field1 >= field3
THEN field1
WHEN field2 >= field3
THEN field2
ELSE field3
END
ELSE
NULL
END AS greatest
FROM my_table
Следующее предложение SQL даже более краткое, чем Onedaywhen's Ответ, хотя они семантически эквивалентны:
SELECT CASE WHEN field1 >= ALL(field2, field3, field4) THEN field1
WHEN field2 >= ALL( field3, field4) THEN field2
WHEN field3 >= ALL( field4) THEN field3
ELSE field4
END AS greatest
FROM my_table;
Это, наконец, редкий и все же хороший вариант использования для тех квантификаторов, которые вряд ли кто-либо использует в SQL. Смотрите также этот вопрос:
Являются ли SQL какие -либо и некоторые ключевые слова на всех диалектах SQL?
К сожалению, этот синтаксис не поддерживается во всех диалектах SQL, как ALL
Quantifier USUSALLY ожидает <table subquery>