2009-06-25 38 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是天賜之物:-)