代码之家  ›  专栏  ›  技术社区  ›  TheTXI

TSQL:从具有最低正值的列集合中选择

  •  2
  • TheTXI  · 技术社区  · 16 年前

    模式示例:

    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
    

    基于这个示例表,我希望能够以最有效/最简单的方式在四个*Price列之间选择最低的非零值。

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

    有关更多信息,数据库是SQLServer2005。

    3 回复  |  直到 16 年前
        1
  •  4
  •   Quassnoi    16 年前
    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 倍于 案例 声明。

    以下是分析并产生正确结果的测试脚本:

    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
    
        2
  •  3
  •   Paul Chernoch    16 年前

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

    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来解决问题,并将NULL替换为一个大的负数或零,如果您不希望出现任何负价格。假设没有负价格,我将使用零。

    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。)

        3
  •  0
  •   Dan F    16 年前

    我回答这个问题有点晚了,但是 UNPIVOT 可能在这里也很方便。4列可能还不算太糟糕,但当您看到30列要取消交叉表时,UNPIVOT是天赐之物:-)

    推荐文章