2013-07-30 1 views
1

저는 SQL에 매우 익숙합니다.SQL 고객별로 그룹화 할 때 첫 번째 가격을 선택하십시오.

내 데이터는 고객 계약 번호, 서비스 날짜 및 가격 목록으로 구성됩니다. 나는 고객별로 그룹화 할 수 있어야하고, 첫 번째 가격을 서비스 날짜까지 가져오고 다른 열은 모든 가격의 합계를 가져야합니다.

그래서 내가 좋아하는 뭔가가 있습니다

SELECT 
CONTRACT, 
SUM(PRICES) as [TOTAL SPENT] 
FIRST(PRICE) as [FIRST PRICE] 
FROM TABLE 
GROUP BY CONTRACT 
ORDER BY CONTRACT 

을하지만, 분명히 첫 번째는 (내가 Microsoft SQL Server를 사용하고 있습니다) 함수 이름에 내장되지 않습니다. 어떤 제안?

미리 감사드립니다.

+1

SQL을 제공하여 필요한 테이블/필드를 만들 수 있습니까? – Robadob

+0

어떤 버전의 SQL Server를 사용 하시겠습니까? –

+0

당신은 "서비스 날짜별로 첫 번째 가격을 끌어 오십시오"라고 말했지만 서비스 날짜가 선택 항목에서 검색되지 않습니다 ... 그래서 어떤 가격이 "첫 번째"가격입니까? 샘플 데이터와 원하는 결과가 잘 보일 것입니다 –

답변

1

보십시오 :이 같은

-- @tmp represents your table 
    declare @tmp table (
    [Contract] int, 
    [Prices] decimal(18,5), 
    [ServiceDate] datetime 
    ) 

    -- some testing data - you may skip that 
    insert into @tmp values(1, 100, '2011-01-01') 
    insert into @tmp values(1, 200, '2011-01-02') 
    insert into @tmp values(2, 10, '2011-01-01') 
    insert into @tmp values(2, 20, '2011-01-02') 
    insert into @tmp values(2, 30, '2011-01-03') 


    SELECT 
     [CONTRACT], 
     SUM(PRICES) as [TOTAL SPENT], 
     (SELECT TOP 1 t2.PRICES FROM @tmp t2 
     WHERE t2.[Contract] = t1.[Contract] 
     ORDER BY [SERVICEDATE]) as [FIRST PRICE] 
    FROM @tmp t1 
    GROUP BY [CONTRACT] 
    ORDER BY [CONTRACT] 
2

당신은 ROW_NUMBER를 사용할 수 있습니다

WITH CTE AS(
    SELECT CONTRACT, 
      SUM(PRICES) OVER(PARTITION BY CONTRACT) as [TOTAL SPENT], 
      PRICE as [FIRST PRICE], 
      ROW_NUMBER()OVER(PARTITION BY Contract Order By ServiceDate) 
    FROM TABLE 
) 
SELECT CONTRACT, [TOTAL SPENT], [FIRST PRICE] 
FROM CTE 
WHERE RN = 1 
ORDER BY CONTRACT 

이것은 ServiceDate에 따라 각 계약-그룹에서 첫 번째 행을 선택합니다. 이 방법은 집계 함수를 사용하거나 GROUP BY에 포함 할 필요없이 모든 열을 선택할 수 있다는 이점이 있습니다. 최소한의 SQLServer이 필요합니다 2005

0

뭔가 :

SELECT 
    CONTRACT, 
    SUM(PRICE) as [TOTAL SPENT], 
    (SELECT TOP 1 PRICE FROM [TABLE] 
    WHERE CONTRACT_DATE = MIN(T.CONTRACT_DATE) 
    AND CONTRACT = T.CONTRACT) AS [FIRST PRICE] 
    FROM [TABLE] T 
    GROUP BY CONTRACT 
    ORDER BY CONTRACT 

SQL Fiddle demo를 참조하십시오.

+0

중복이 있다면 어떻게 될까요? 상관 관계가있는 하위 쿼리는 적어도 TOP 1이 필요합니다. 그러나 이것이 어떤 경우에도 가장 효율적인 접근 방법이 될 것이라고는 생각하지 않습니다. –

+0

@AaronBertrand 좋은 점, 실제로 쓰는 동안 'TOP 1'에 대해 생각했지만 추가하는 것을 잊어 버렸습니다. 현재 편집 된 답변입니다. 효율성에 관해서는, 데이터의 토루가없는 한 실제로는 문제가되지 않을 것입니다 (그리고 subselect에서 'MIN'을 사용하는 것이 확실히 다른 게시물에서 제안 된 것처럼 'ORDER BY'보다 훨씬 효율적입니다). –

+0

글쎄, 정말 달라집니다. 그것을 지원할 색인이 있다면, 그 순서를 사용하여 row_number를 생성하는 것은 모든 행에 대해 MIN을 스캔하는 것보다 훨씬 더 효율적입니다. –

관련 문제