2009-06-25 42 views
2

示例模式的一组列的选择:TSQL:从最低正值

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中

回答

4
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报表更具可读性。

但是请注意,这大约是时间慢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 
+0

LEAST函数是TSQL真正需要的一件事。 – Welbog 2009-06-25 12:46:05

+0

@ Welbog:是的。但是由于我们在这里只需要积极的价值,在这种情况下,它仍然是一堆CASE声明。 – Quassnoi 2009-06-25 12:47:48

3

我会用一个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

我有点迟到这个特定的问题,但UNPIVOT也可能在这里得心应手。 4列可能并不算太差,但是当您查看30列时,您想要un crosstab,UNPIVOT是天赐之物:-)