示例架构:
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
有关额外信息,数据库是SQL Server 2005。
答案 0 :(得分: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
语句更具可读性。
但请注意,这大约是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
答案 1 :(得分:3)
我会使用案例陈述:
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。)
答案 2 :(得分:0)
我对这个特定问题有点迟了,但UNPIVOT也可能在这方面很方便。 4列可能不是太糟糕,但当你看到30个你想要取消交叉表的列时,UNPIVOT是天赐之物: - )