TSQL: выберите из набора столбцов с наименьшим положительным значением - PullRequest
2 голосов
/ 25 июня 2009

Пример схемы:

RowID    Quantity    ModifiedPrice    GroupPrice    CustomPrice    SalePrice
----------------------------------------------------------------------------
1        5           20.00            0             15.00          17.00
2        2           14.00            7.00          22.00          0
3        9           10.00            10.00         0              11.00

Исходя из этого примера таблицы, я хотел бы иметь возможность выбрать самое низкое ненулевое значение между четырьмя * столбцами цены наиболее эффективным / простым способом.

Пример вывода:

RowID    Quantity    EndPrice
------------------------------
1        5           15.00
2        2           7.00
3        9           10.00

Для дополнительной информации, БД - SQL Server 2005.

Ответы [ 3 ]

4 голосов
/ 25 июня 2009
SELECT  RowId, Quantity,
        (
        SELECT  MIN(price)
        FROM    (
                SELECT  ModifiedPrice AS price
                UNION ALL
                SELECT  GroupPrice
                UNION ALL
                SELECT  CustomPrice
                UNION ALL
                SELECT  SalePrice
                ) qi
        WHERE   price > 0
        )
FROM    mytable

Это более читабельно, чем набор CASE операторов.

Обратите внимание, что это примерно в 4 раз медленнее, чем CASE операторов.

Вот тестовый скрипт, который анализирует и выдает правильные результаты:

CREATE TABLE #t_prices
        (
        RowID INT NOT NULL,
        Quantity INT NOT NULL,
        ModifiedPrice FLOAT NOT NULL,
        GroupPrice FLOAT NOT NULL,
        CustomPrice FLOAT NOT NULL,
        SalePrice FLOAT NOT NULL
        )

INSERT
INTO    #t_prices
VALUES  (1, 5, 20.00, 0, 15.00, 17.00)
INSERT
INTO    #t_prices
VALUES  (2, 2, 14.00, 7.00, 22.00, 0)
INSERT
INTO    #t_prices
VALUES  (3, 9, 10.00, 10.00, 0, 11.000)


SELECT  RowId, Quantity,
        (
        SELECT  MIN(price)
        FROM    (
                SELECT  ModifiedPrice AS price
                UNION ALL
                SELECT  GroupPrice
                UNION ALL
                SELECT  CustomPrice
                UNION ALL
                SELECT  SalePrice
                ) qi
        WHERE   price > 0
        )
FROM    #t_prices
3 голосов
/ 25 июня 2009

Я бы использовал оператор case:

CASE
  WHEN condition THEN trueresult
  [...n]
[ELSE elseresult]
END

Начиная с незагроможденного ответа, предположим, что ни одно из значений не равно NULL:

CASE 
  WHEN ModifiedPrice > GroupPrice AND ModifiedPrice > CustomPrice AND ModifiedPrice > SalePrice THEN ModifiedPrice
  WHEN GroupPrice > CustomPrice AND GroupPrice > SalePrice THEN GroupPrice
  WHEN CustomPrice > SalePrice THEN CustomPrice
  ELSE SalePrice
END

Если какие-либо значения равны NULL, эти условия будут возвращать false, поэтому нам нужно использовать ISNULL, чтобы исправить ситуацию и заменить NULLS большим отрицательным числом или нулем, если вы не ожидаете отрицательных цен. При условии отсутствия отрицательных цен, я буду использовать ноль.

CASE 
  WHEN ModifiedPrice > ISNULL(GroupPrice, 0) AND ModifiedPrice > ISNULL(CustomPrice, 0) AND ModifiedPrice > ISNULL(SalePrice,0) THEN ModifiedPrice
  WHEN GroupPrice > ISNULL(CustomPrice, 0) AND GroupPrice > ISNULL(SalePrice, 0) THEN GroupPrice
  WHEN CustomPrice > ISNULL(SalePrice, 0) THEN CustomPrice
  ELSE ISNULL(SalePrice, 0)
END

Не красиво, но это будет работать. Если вы выполняете некоторую статистику, чтобы увидеть, какой столбец обычно является наибольшим значением, вы можете изменить запрос, чтобы сначала проверить этот столбец. (Вы не можете просто изменить мои предложения WHEN, как написано, поскольку каждый из них предполагает, что предыдущая цена уже была отклонена. Если бы CustomPrice обычно был самым большим, я бы поменял местами ModifiedPrice и CustomPrice в приведенном выше коде.)

0 голосов
/ 27 июня 2009

Я немного опоздал на этот конкретный вопрос, но UNPIVOT также мог бы пригодиться и здесь. 4 столбца, вероятно, не так уж и плохи, но когда вы смотрите на 30 столбцов, которые хотите удалить из перекрестной таблицы, UNPIVOT - это находка: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...