Как смоделировать наибольшее () в Sybase ASE?

StackOverflow https://stackoverflow.com/questions/8825866

  •  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>

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top