2015-02-02 6 views
1

다음과 유사한 데이터가있는 테이블이 있습니다.부울 값이 참인 열 값을 가져오고, 그렇지 않으면 부울 값이 거짓 일 때 열 값을 가져옵니다.

다양한 플래그와 키가있는 수많은 행이있는 큰 테이블을 사용하고 있습니다. 나는 깃발이 진실 인 곳을 가장 낮게, 깃발이 틀린 곳을 가장 낮게되도록 그들을 묶어 놓았다. 참과 거짓 플래그가있는 경우

╔══════════════════╦══════╦═══════╗ 
║  Email  ║ Flag ║ Key ║ 
╠══════════════════╬══════╬═══════╣ 
║ [email protected] ║ 1 ║ 77731 ║ 
║ [email protected] ║ 0 ║ 67980 ║ 
║ [email protected] ║ 1 ║ 64417 ║ 
║ [email protected] ║ 0 ║ 71733 ║ 
║ [email protected] ║ 1 ║ 95655 ║ 
║ [email protected] ║ 0 ║ 91016 ║ 
╚══════════════════╩══════╩═══════╝ 

지금, 각각 별개의 이메일, 나는 진정한 키 값을 반환합니다. 그렇지 않으면 가장 낮은 값을 반환하고 싶습니다. 나는 앞의 두 경우 문을 사용하여, 그룹의 모든 종류의 시도 절을 꾸게

╔══════════════════╦══════╦═══════╗ 
║  Email  ║ Flag ║ Key ║ 
╠══════════════════╬══════╬═══════╣ 
║ [email protected] ║ 1 ║ 77731 ║ 
║ [email protected] ║ 1 ║ 64417 ║ 
║ [email protected] ║ 1 ║ 95655 ║ 
║ [email protected] ║ 0 ║ 91016 ║ 
╚══════════════════╩══════╩═══════╝ 

을하지만, 그 방법을 볼 수 없습니다 :

그래서 출력은 이상적으로 같을 것이다 .

정말 도움이된다면 전자 메일과 키만 필요합니다.

답변

1

여기에는 두 가지가 있습니다.

방법 1

는이 같은 CTE와 함께 할 수 있습니다 :

WITH data_cte AS (
    SELECT Email, MAX(CAST(Flag AS INT)) AS Flag 
    FROM Data 
    GROUP BY Email) 
SELECT Data.* 
FROM data_cte 
JOIN Data 
    ON Data.Email = data_cte.Email 
    AND Data.Flag = data_cte.Flag 

을 해제 구성하기가의 CTE 부분은 단지 (각 이메일에 대한 필요성을 플래그의 MAX 값을 가져옵니다 CAST에서 INT으로 MAXBIT 열로 표시 할 수 없습니다. 나머지 쿼리는 CTE를 다시 테이블에 연결하여 관련 데이터 행을 가져옵니다.

방법 2

UNION 사용 :

SELECT * 
FROM Data 
WHERE Flag = 1 

UNION 

SELECT * 
FROM Data 
WHERE Flag = 0 
AND NOT EXISTS(SELECT * 
       FROM Data AS InnerData 
       WHERE InnerData.Flag = 1 
       AND InnerData.Email = Data.Email) 
+0

감사합니다 아주 많이. CTE는 매력처럼 일했습니다. 나는 이전에 약간 비슷한 점을 생각 했었지만, 이것과 같이 집합체가 꽤 복잡하다고 생각하지 않습니다. 나는 이미 노조와 비슷한 것을 시도해 보았지만, 테이블의 크기 때문에 조금 더 커지게되었다. 두 옵션 모두에 대해 높이 평가되었습니다! – Reisclef

0
SELECT 
    A.Email 
    ,CASE WHEN A.Cf > A.Sf THEN Mk ELSE Key END AS ChosenKey 
FROM 
    (
    SELECT 
     Email 
     ,Key 
     ,COUNT(Flag) Cf 
     ,MIN(Key) OVER(PARTITION BY Email ORDER BY Key ASC) AS Mk 
     ,SUM(Flag) OVER(PARTITION BY Email) Sf 
    FROM 
     Table 
    ) AS A 

아마 그런 일에서 작업? 그리고 당신은 또한 윈도우 기능을 통해 이러한 목표를 달성 할 수

+0

솔루션으로도 작동하는 것처럼 보입니다. 제안 해 주셔서 감사합니다. – Reisclef

0

등 당신의 중복을 제거 :

SELECT email, flag, key FROM (
    SELECT email, flag, key, ROW_NUMBER() OVER (PARTITION BY email ORDER BY flag DESC) AS rn 
     FROM mytable 
) x1 
WHERE rn = 1; 
+0

Row_Number를 잘 사용합니다. 그걸 고려하지 않았고 전에는 그런 종류의 문법을 본적이 없었습니다. 그것을 명심하십시오! – Reisclef

관련 문제