2010-07-09 23 views
7

Tôi có Db và truy vấn sau. Truy vấn nhận hai tham số: cột sắp xếp và hướng. Tuy nhiên, tôi phải thêm sắp xếp tùy chỉnh vào truy vấn (dựa trên Fuji nên đến trước và Gala thứ hai, v.v.). Phần này cũng làm việc nhưng nó tạo mã trùng lặp trong truy vấn của tôi. Bởi vì điều đó, tôi khá chắc chắn mọi người sẽ không cho phép tôi kiểm tra điều này. Vì vậy, câu hỏi của tôi là: là có một cách để không lặp lại tuyên bố CASE?Thứ tự sắp xếp tùy chỉnh - Cách không sao chép câu lệnh 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 

Cảm ơn!

Trả lời

5

Bạn có thể nhân lên phím sắp xếp theo một trong hai +1 hoặc -1 tùy thuộc vào việc ASC hoặc DESC được yêu cầu:

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

Tại sao không có một bảng giá trị tương đương, tham gia vào các cột khác nhau, và sắp xếp trên giá trị so sánh.

Ví dụ:

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 

Bạn sẽ không thực hiện mẹo này trong khi có thêm một chút cơ sở dữ liệu?

Tôi không thực sự lắm, do đó cú pháp có thể khá hỏng. Tôi khá không hài lòng với khái niệm 'CASE' trong SQL mặc dù.

3

Kể từ khi bạn đang ở trên SQL 2008, bạn có thể sử dụng một 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 

Nó không phải là trơn như * -1 giải pháp cho vấn đề cụ thể này, nhưng nó có thể được điều chỉnh cho các tình huống khác mà bạn muốn tránh trùng lặp mã.

Các vấn đề liên quan