2010-08-06 2 views
2

나는 내 마음을 감쌀 수없는 SQL 쿼리를 가지고있다. 나는 많은 양의 SQL 경험이 없다. 영어간단한 SQL 문제

Social Security No (SSN). 
Name. 
organisation. (Finance/IT) 

내가 원하는 것은 :

다른 이름이 "금융"의 모든 사회 보장 번호 (SSN) 및 이름을 선택하려면 그래서

내가 테이블 XXX가 도움이 필요합니다 "IT"에서 그 SSN에 대해.

내 작동하지 않는 시도 :

선택 SSN, 이름이 XXX에서 어디서하지

(XXX에서 조직 = "IT"와 SSN = the_first_ssn을 이름을 선택)에서 조직 = "금융"이름

도와주세요.


나는 그것을 조금 더 어렵게 만들기로 결정했습니다.

SSN은 "IT"에서 여러 번 OCUR 수 있습니다

그래서 내가 "IT"

답변

3

에 SSN가 같은 이름으로 존재하지 않는 모든 사회 보장 번호 (SSN) 및 금융에서 이름을 선택합니다 당신 exists 절에 하위 쿼리를 사용할 수 있습니다

select ssn, name 
from YourTable a 
where organisation = 'Finance' 
     and exists 
     (
     select * 
     from YourTable b 
     where organisation = 'IT' 
       and a.ssn = b.ssn 
       and a.name <> b.name 
     ) 

하위 쿼리는 같은 SSN하지만 다른 이름으로 IT의 행이 있어야 말한다.

+0

이것은 정확하게 내가 원하는 것입니다. 내가 테이블을 "a"로 저장해야 할 필요가있는 것처럼 보인 다음에는 원래의 querys 데이터를 rweference 할 수 있습니다. 완벽합니다. 감사합니다. – Mark

1

select ssn, name 
from XXX XXX1 
where org = "Finance" 
and ssn in 
(
select ssn 
from XXX XXX2 
where org="IT" 
and XXX1.name<>XXX2.name 
) 
0
SELECT distinct 
t1.ssn, 
t1.name 
from 
xxx t1 
inner join xxx t2 on t1.ssn=t2.ssn and t1.name<>t2.name 
where t1.org='Finance' and t2.org='IT' 
0

... SSN은 고유 키입니다 가정 나는 파티에 늦었 알지만, SQL을 배우는 중이 야하고 나는 나의 손을 원했고 해결책을 찾고 기존 답변과 비교하십시오. 나는 약간의 테스트 데이터를 가지고 테이블 Personnel을 만들었다.

  1. 내 SQL 서버 만 쿼리는 CTE를 사용하고 INNER JOIN :

    WITH 
        Finance AS (SELECT SSN, Name FROM Personnel WHERE Org = 'Finance'), 
        IT AS (SELECT SSN, Name FROM Personnel WHERE Org = 'IT') 
    SELECT Finance.SSN, Finance.Name 
        FROM Finance 
        INNER JOIN IT ON IT.SSN = Finance.SSN 
        WHERE IT.Name != Finance.Name 
    
  2. Alexander's solution는 직선 INNER JOIN를 사용합니다.

    SELECT Finance.SSN, Finance.Name 
        FROM Personnel Finance 
        INNER JOIN Personnel IT ON Finance.SSN = IT.SSN 
        WHERE 
         (Finance.Org = 'Finance' AND IT.Org = 'IT') AND 
         (Finance.Name != IT.Name) 
    
  3. Andomar's solution을 상관 하위 쿼리를 사용하여 EXISTS 절 내부 :

    SELECT SSN, Name 
        FROM Personnel a 
        WHERE 
         (Org = 'Finance') AND 
         EXISTS 
         (
          SELECT * 
           FROM Personnel b 
           WHERE (Org = 'IT') AND (a.SSN = b.SSN) AND (a.Name != b.Name) 
         ) 
    
  4. 나는 그것이 필요하지이기 때문에 WHERE 절에 이름 비교 퍼팅, 그리고 DISTINCT을 떨어 뜨리고, 그것을 조금 재 작성 barrylloyd's solutionIN 절 내 상관 된 하위 쿼리 사용 :

    SELECT SSN, Name 
        FROM Personnel p1 
        WHERE 
         (Org = 'Finance') AND 
         SSN IN 
         (
          SELECT SSN FROM Personnel p2 
           WHERE (Org = 'IT') AND (p1.Name != p2.Name) 
         ) 
    

이 모든 것을 SQL Server에 연결했는데 쿼리 1과 2가 모두 동일한 쿼리 계획을 생성하고 쿼리 3과 4가 동일한 쿼리 계획을 생성하는 것으로 나타났습니다. 두 그룹의 차이는 이전 그룹이 실제로는 INNER JOIN을 내부적으로 수행하는 반면 후자 그룹은 왼쪽 세미 조인을 수행한다는 것입니다. (의 조인 다른 유형에 대한 설명 See here.)

내가 선호하는 약간의 성능 이점이 있으리라 믿고있어 왼쪽 반에 가입; 그러나 비즈니스 사례의 경우 오른쪽 표의 데이터 열을보고 싶다면 (예를 들어, 을 모두 표시하려면 이름을 표시하려는 경우) INNER JOIN을 사용하려면 해당 쿼리를 완전히 다시 작성해야합니다. 기반 솔루션입니다.

성능이 3과 4와 비슷하기 때문에 해결 방법 2가 좋을 것입니다. 또한 성능이 훨씬 뛰어납니다. 내 솔루션은 SELECT 문을 읽기가 매우 쉽지만 2보다 길고 이식성이 뛰어납니다. 두 개의 "하위 테이블"각각에 대해 추가 필터링을 수행해야하거나이 쿼리의 결과가 추가 목표의 중간 단계로 사용되는 경우 가독성을 위해 더 나은 것으로 생각됩니다.