2010-05-17 5 views
2

내 SQL 쿼리는 열을주는 결과 :주문 SQL 쿼리는

  • pnl (정수)
    • product_id - 내가 이상을 얻을 수 (부동 인 음수가 될 수 있습니다)

    가 100 행.

    abs (pnl)을 기준으로 상위 40 개 행을 필터링하려고합니다. 하지만 결과는 abs (pnl)이 아닌 pnl 열에 의해서만 정렬되어야합니다. 이 작업을 수행 할 수있는 방법이

    내가

    MSSQL 2005에 대해이 작업을 수행 할 수 있습니까?

  • 답변

    7

    단일 단계/문장으로는이 작업을 수행 할 수 없습니다. TOP x 선택은 항상 ORDER BY 주문 지침을 기반으로합니다. ABS(pnl)을 기반으로 TOP 40을 선택할 수없고 동시에 다른 순서로 주문할 수 없습니다.

    CTE (Common Table Expression) 또는 임시 테이블을 사용하는 두 단계 프로세스 - 먼저 ABS(pnl)으로 정렬 된 TOP 40 행을 선택한 다음 pnl으로 결과 집합을 정렬하십시오.

    뭔가처럼 : 그 PRODUCT_ID를 가정하면 테이블의 기본 키가 아닌

    WITH Top40Rows AS 
    (
        SELECT TOP 40 product_id, pnl 
        ORDER BY ABS(pnl) 
    ) 
    SELECT product_id, pnl 
    FROM Top40Rows 
    ORDER BY pnl 
    
    +1

    +! : 먼저했다. –

    3

    ,이 같은 것을 수행 할 수 있습니다 OMG 조랑말으로

    Select ... 
    From Table 
        Join (
          Select TOP 40 TablePK 
          From Table 
          Order by Abs(pnl) Desc 
          ) As Z 
         On Table.TablePK = Z.TablePK 
    Order By Table.pnl ASC  
    

    언급을, 당신이 할 수 단일 파생 테이블로 표시 :

    Select ... 
    From (
         Select TOP 40 ..... 
         From Table 
         Order by Abs(pnl) Desc 
         ) As Z 
    Order By Z.pnl ASC  
    

    CTE를 사용하려면 RO W_NUMBER 기능 :

    With RankedItems As 
        (
        Select ... 
         , ROW_NUMBER() OVER (ORDER BY Abs(Table.pnl)) As ItemRank 
        From Table 
        ) 
    Select 
    From RankedItems 
    Where ItemRank <= 40 
    Order By pnl ASC 
    
    +0

    @OMG 포니 (Ponies) - 십자가 조인이나 존재하는 성명서를 사용하여 할 수 있지만 내부 조인은 더 간단합니다. – Thomas

    +0

    @OMG 포니 (Ponies) - 전체 TOP 연산을 결합 테이블을 제거 할 수있는 파생 테이블로 만들 수 있다고 가정합니다. – Thomas

    +0

    +1 : 업데이트의 경우 ROW_NUMBER는 모든 테이블 내용을 구문 분석하기 때문에 대안이 아닙니다. –

    0

    그냥 완전성에 대해,이 @marc_s로서가 아니라 CTE를 사용하지 않고 동일합니다

    SELECT product_id, pnl FROM (
        SELECT TOP 40 product_id, pnl FROM tbl ORDER BY abs(pnl)) x 
    ORDER BY pnl