我有以下Db和查询。该查询采用两个参数:排序列和方向。但是,我必须在查询中添加自定义排序(基于富士应该先来,然后是Gala,等等)。这部分也可以工作,但它在我的查询中创建重复的代码。因此,我很确定人们不会让我检查这个。所以我的问题是:有没有办法不重复CASE声明?
CREATE TABLE Fruits (
[type] nvarchar(250),
[variety] nvarchar(250),
[price] money
)
GO
INSERT INTO Fruits VALUES ('Apple', 'Gala', 2.79)
INSERT INTO Fruits VALUES ('Apple', 'Fuji', 0.24)
INSERT INTO Fruits VALUES ('Apple', 'Limbertwig', 2.87)
INSERT INTO Fruits VALUES ('Orange', 'Valencia', 3.59)
INSERT INTO Fruits VALUES ('Pear', 'Bradford', 6.05)
DECLARE @sortColumnName nvarchar(MAX) = 'Variety'
DECLARE @sortDirection nvarchar(MAX) = 'ASC'
SELECT ROW_NUMBER() OVER (ORDER BY
CASE WHEN @sortColumnName = 'Variety' AND @sortDirection = 'ASC'
THEN
CASE f.Variety
WHEN 'Fuji' THEN 1
WHEN 'Gala' THEN 2
ELSE 3
END
END ASC,
CASE WHEN @sortColumnName = 'Variety' AND @sortDirection = 'DESC'
THEN
CASE f.Variety
WHEN 'Fuji' THEN 1
WHEN 'Gala' THEN 2
ELSE 3
END
END DESC), *
FROM Fruits f
答案 0 :(得分:5)
您可以将排序键乘以+1或-1,具体取决于是否请求ASC或DESC:
SELECT ROW_NUMBER() OVER (ORDER BY
CASE WHEN @sortColumnName = 'Variety'
THEN
(CASE f.Variety
WHEN 'Fuji' THEN 1
WHEN 'Gala' THEN 2
ELSE 3
END)
END
* (CASE WHEN @sortDirection = 'ASC' THEN 1 ELSE -1 END)), *
FROM Fruits f
答案 1 :(得分:3)
由于您使用的是SQL 2008,因此可以使用CTE:
;WITH CTE AS
(
SELECT
CASE WHEN @sortColumnName = 'Variety' THEN
CASE f.Variety
WHEN 'Fuji' THEN 1
WHEN 'Gala' THEN 2
ELSE 3
END
END AS sort_column,
*
FROM
Fruits F
)
SELECT
ROW_NUMBER() OVER (
ORDER BY
CASE WHEN @sortDirection = 'DESC' THEN sort_column ELSE 0 END DESC,
CASE WHEN @sortDirection = 'ASC' THEN sort_column ELSE 0 END ASC),
type,
variety,
price
FROM
CTE
它不像这个特定问题的* -1解决方案那样光滑,但它可以适用于你想避免代码重复的其他情况。
答案 2 :(得分:1)
为什么没有另一个可比值的表,在品种列上加入,并对比较值进行排序。
E.g。
INSERT INTO FruitSort VALUES ('Gala', 2)
INSERT INTO FruitSort VALUES ('Fuji', 1)
SELECT ROW_NUMBER() OVER (ORDER BY FruitSort.sortvalue)
FROM Fruits f
JOIN FruitSort
ON FruitSort.variety == Fruits.variety
在更多数据库y的同时,这也不会成功吗?
我不是很练习,所以语法可能很破碎。我对SQL中'CASE'语句的概念非常不满意。