2010-07-09 2 views
7

다음 Db 및 쿼리가 있습니다. 쿼리는 정렬 열과 방향의 두 가지 매개 변수를 사용합니다. 그러나 사용자 지정 정렬을 쿼리에 추가해야합니다 (Fuji가 먼저 시작해야하고 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 

고마워요!

답변

5

당신은 하나 하나에 의해 정렬 키를 곱하면 -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

왜 비교 값에 대한 또 다른 테이블이없는, 다양한 컬럼에 가입하고, 종류 비교 값에.

예.

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'문 개념에 대해 상당히 불만 스럽다.

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 솔루션처럼 매끄러운 아니지만, 다른 상황에 적용 할 수 있습니다 어디 코드 중복을 피하고 싶습니다.