2013-06-04 2 views
2

다음과 비슷한 시나리오가 있는데 최대 3 열을 찾고 싶습니다.이 열을 찾는 데 사용하는 매우 긴 방법처럼 보입니다. mx .여러 열의 최대 값

더 짧은 해결책은 무엇입니까? 이 연령대의 결합 된 최대 필요한 경우

CREATE TABLE #Pig 
(
    PigName CHAR(1), 
    PigEarlyAge INT, 
    PigMiddleAge INT, 
    PigOldAge INT 
) 

INSERT INTO #Pig VALUES 
('x',5,2,3), 
('y',2,9,5), 
('z',1,1,8); 

WITH Mx_cte 
    AS 
    (
    SELECT PigName, 
      Age = PigEarlyAge 
    FROM #Pig 
    UNION 
    SELECT PigName, 
      Age = PigMiddleAge 
    FROM #Pig 
    UNION 
    SELECT PigName, 
      Age = PigOldAge 
    FROM #Pig 
    ) 
SELECT x.PigName, 
     x.PigEarlyAge, 
     x.PigMiddleAge, 
     x.PigOldAge, 
     y.mx 
FROM #Pig x 
     INNER JOIN 
     (
     SELECT PigName, 
       mx = Max(Age) 
     FROM Mx_cte 
     GROUP BY PigName 
     ) y 
     ON 
      x.PigName = y.PigName 
+0

연령대 요약이 필요합니까? –

+0

@YuriyGalanter - 조금 모호한 경우 결과는 포스트에 포함 된 스크립트와 정확히 일치해야합니다. – whytheq

답변

4

SQL Server에는 값 목록을 허용하고 가장 큰 값을 반환하는 다른 RDBMS에서 GREATEST 기능과 동일한 기능이 없습니다.

그러나 원하는 열로 구성된 table valued constructor을 사용하여 비슷한 것을 시뮬레이트 한 다음 MAX을 적용 할 수 있습니다.

SELECT *, 
     (SELECT MAX(Age) 
     FROM (VALUES(PigEarlyAge), 
         (PigMiddleAge), 
         (PigOldAge)) V(Age)) AS mx 
FROM #Pig 
+0

+1 간결함 - 호출 된 것과 같은'VALUES'의 사용은 무엇입니까? - MSDN 등에서 어떤 구절을 검색합니까? – whytheq

+1

@whytheq [Table Value Constructor] (http://msdn.microsoft.com/en-us/library/dd776382.aspx) –

+0

링크에 감사드립니다. TVC와 관련이있는 것처럼 보입니까? – whytheq

0

, 당신은 간단한 최대 기능의 내부에 추가 할 수 있습니다 :

SELECT PigName, MAX(PigEarlyAge + PigMiddleAge + PigOldAge) as MaxAge 
FROM #Pig 
GROUP BY PigName 
+0

어쩌면 내 질문이 약간 모호합니다 - 나는 OPA가 MaxAge에 대해 반환하는 것과 동일한 결과를 원합니다. 단지 짧은 방식으로 쿼리 할 수 ​​있기를 원합니다. – whytheq

1

을 당신이 세 필드의 최대하려면 다음

select (case when max(PigEarlyAge) >= max(PigMiddleAge) and max(PigEarlyAge) >= max(PigOldAge) 
       then max(PigEarlyAge) 
       when max(PigMiddleAge) >= max(PigOldAge) 
       then max(PigMiddleAge) 
       else max(PigOldAge) 
     end) 
    from #Pig 

을 각각의 최대 값을 가진 행을 찾으려면 union과 함께 row_number()을 사용하십시오.

select p.PigName, PigEarlyAge, PigMiddleAge, PigOldAge, 
     (case when PigEarlyAge >= PigMiddleAge and PigEarlyAge >= PigOldAge then PigEarlyAge 
      when PigMiddleAge >= PigOldAge then PigMiddleAge 
      else PigOldAge 
     end) as BigAge 
from (select p.*, 
      row_number() over 
        (order by (case when PigEarlyAge >= PigMiddleAge and PigEarlyAge >= PigOldAge then PigEarlyAge 
            when PigMiddleAge >= PigOldAge then PigMiddleAge 
            else PigOldAge 
           end) desc 
        ) seqnum as seqnum 
     from #Pig p 
    ) p 
where p.seqnum = 1; 

중복 값을 원할 경우 row_number() 대신 rank()을 사용하십시오.

+0

감사합니다. gordon - +1 흥미로운 게시물. – whytheq