2017-12-15 12 views
2

특정 사용자를 위해 테이블을 검색하는 쿼리를 작성하고 있습니다.이 테이블은 정확한 일치 항목과 일치하는 항목을 제공합니다."순위"가있는 SQL 통합

본질적으로 사용자 이메일 주소는 고유하므로이 행 이상을 반환 할 필요는 없지만 모든 잠재 사용자를 일치시킬 확률의 '순위'와 함께 모든 잠재 사용자를 반환해야합니다.

가능한 한 효율적으로 쿼리를 작성하고이 시점에서 필자는 커서를 사용하지 않아야 커서를 피할 수 있습니다. 다음은 현재 쿼리의 예입니다. 이메일 주소가 일치하는 경우

SELECT 
      tt.userId, 
      tt.UserName, 
      ad.*, 
      1 AS 'Rank' 
     FROM 
      Users.User tt 
     LEFT JOIN 
      General.[Address] ad ON tt.AddressId = ad.AddressId 
     WHERE 
      tt.EmailAddress = @EmailAddress 
    UNION 

     SELECT 
      tt.userId, 
      tt.UserName, 
      ad.*, 
      2 AS 'Rank' 
     FROM 
      Users.User tt 
     LEFT JOIN 
      General.[Address] ad ON tt.AddressId = ad.AddressId 
     WHERE 
      tt.LastName = @LastName 
      AND tt.BirthDate = @DOB 

은 분명히 여기에 주요 결함은, 동일한 사용자는 등 두 번째 쿼리에 표시 될 것입니다. 또한 이러한 검색 순위를 매길 필요가있을 때 노동 조합은 행을 복제본과 일치시키지 않으므로 동일한 사용자를 몇 번 뒤로 가져옵니다.

모든 조언을 크게 듣습니다.

+0

** 올바르게 이해하고 있습니까? if ** 이메일 주소를 가진 사용자가 발견되면 성 및 생년월일에 일치가 나타나지 않아야합니까? – Larnu

+0

정확합니다. 정확히 내가 후한 것입니다. – Dan

답변

2

당신은 모든 union 필요하지 않습니다 :

SELECT tt.userId, tt.UserName, ad.*, 
     (CASE WHEN tt.EmailAddress = @EmailAddress THEN 1 
      WHEN tt.LastName = @LastName AND tt.BirthDate = @DOB THEN 2 
     END) as [Rank] 
FROM Users.User tt LEFT JOIN 
    General.[Address] ad 
    ON tt.AddressId = ad.AddressId 
WHERE (tt.EmailAddress = @EmailAddress) OR 
     (tt.LastName = @LastName AND tt.BirthDate = @DOB); 

물론, 이러한 새로운 순위 세 열이 일치 등의 추가 조건을 쉽게 추가 할 수 있습니다.

+0

감사합니다. 브레인은 금요일에 그냥 녹고있었습니다! 다시 한번 감사드립니다. – Dan

0

샘플 데이터가 없으므로 테스트되지 않았습니다. 어떤 이메일 주소가 발견되지 않는 경우 DENSE_RANK() 당신이 그러나, 2 개 그룹으로 끝날 것을 의미한다

WITH Results AS(
    SELECT tt.UserID, 
      tt.UserName, 
      ad.*, 
      DENSE_RANK() OVER (ORDER BY CASE WHEN tt.EmailAddress = @EmailAddress THEN 0 ELSE 1 END) AS RN 
    FROM Users.[User] tt 
     LEFT JOIN General.[Address] ad ON tt.AddressId = ad.AddressID 
    WHERE tt.EmailAddress = @EmailAddress 
     OR (tt.LastName = @LastName 
     AND tt.BirthDate = @DOB)) 
SELECT * 
FROM Results 
WHERE RN = 1; 

은 모든 결과는 하나의 RN으로 끝낼 것입니다하지 않으면, 일부 DDL 및 소모품 샘플 데이터를 게시하시기 바랍니다 그렇지 않으면 같은 전자 메일 주소를 가진 사람은 RN이 1 인 반면 나머지는 2입니다 (해당 일치 항목이 CTE 외부의 WHERE 절과 함께 표시되지 않음을 의미).