복붙노트

[SQL] SQL : 어떻게 하나의 열에서 여러 기준을 충족하는 하나의 아이디 ( "행")를 선택합니다

SQL

SQL : 어떻게 하나의 열에서 여러 기준을 충족하는 하나의 아이디 ( "행")를 선택합니다

나는 매우 좁은 테이블이 : USER_ID, 조상을.

USER_ID 컬럼은 자명하다.

조상 열은 사용자의 조상이 우박 곳에서 국가를 포함합니다.

사용자가 여러 나라의 조상을 가질 수로 사용자는 테이블에 여러 행을 가질 수 있습니다.

어떻게 내가 그 조상 여러 출신 사용자, 특정 국가를 선택합니까 : 제 질문은 이것이다?

예를 들어, 나에게 잉글랜드, 프랑스와 독일에서 조상을 가지고 있고, 그 기준을 충족 사용자 당 1 개 행을 반환하는 모든 사용자를 보여줍니다.

그 SQL은 무엇인가?

 user_id     ancestry

---------   ----------

    1        England
    1        Ireland
    2        France
    3        Germany
    3        Poland
    4        England
    4        France
    4        Germany
    5        France
    5        Germany

위의 데이터의 경우는 결과가 될 것으로 기대 것 "4"USER_ID 4 잉글랜드, 프랑스와 독일에서 조상을 가지고있다.

미리 감사드립니다.

추신 명확히하기 : 국가가 특정 사용자에 대해 반복되지 않을 것이다, 그래서 네, USER_ID가 / 조상 열이 고유 한 쌍을합니다.

P.P.S. 잉글랜드, 프랑스, ​​독일 (그리고 국가는 임의입니다) - 나는 3 개국 출신 사용자를 찾고 있어요.

P.P.P.S. 나는 특정 RDBMS에 대한 답변의 특정을 찾고 있지 않다. 나는이 문제에 답을 찾고 있어요 "일반적으로합니다."

나는 재생 w 내용 해요 각 쿼리에 대한 조항이 생성 제공 곳에 절을 프로그래밍 할 수있는 곳 (예를 들어, 나는를 구축하는 기능을 구축 할 수 있다는 WHERE / FROM - WHERE 절).

해결법

  1. ==============================

    1.이 시도:

    이 시도:

    Select user_id
    from yourtable
    where ancestry in ('England', 'France', 'Germany')
    group by user_id
    having count(user_id) = 3
    

    마지막 줄은 사용자의 조상은 3 개국을 의미합니다.

  2. ==============================

    2.

    SELECT DISTINCT (user_id) 
    FROM [user]
    WHERE user.user_id In (select user_id from user where ancestry = 'England') 
        And user.user_id In (select user_id from user where ancestry = 'France') 
        And user.user_id In (select user_id from user where ancestry = 'Germany');`
    
  3. ==============================

    3.3 개 국가 중 하나가 사용자

    3 개 국가 중 하나가 사용자

    SELECT DISTINCT user_id
    FROM table
    WHERE ancestry IN('England','France','Germany')
    

    3 개국이 사용자

    SELECT DISTINCT A.userID
    FROM table A
       INNER JOIN table B on A.user_id = B.user_id
       INNER JOIN table C on A.user_id = C.user_id
    WHERE A.ancestry = 'England'
       AND B.ancestry = 'Germany'
       AND C.ancestry = 'France'
    
  4. ==============================

    4.여러 나라 사람들을 얻을 :

    여러 나라 사람들을 얻을 :

    SELECT u1.user_id 
    FROM users u1
    JOIN users u2
    on u1.user_id  = u2.user_id 
    AND u1.ancestry <> u2.ancestry
    

    이 개 특정 국가에서 사람들을 가져 오기 :

    SELECT u1.user_id 
    FROM users u1
    JOIN users u2
    on u1.user_id  = u2.user_id 
    WHERE u1.ancestry = 'Germany'
    AND u2.ancestry = 'France'
    

    3 개 국가의 ... 세 번 가입 할 수 있습니다. 한 번만, 서로 다른 결과를 (들)을 얻을 수 있습니다.

    이 3 줄 (음 ... 카운트)가 다음 선이 허용되는 지정 사용자를 얻을 것이다. 참고 당신은에 UNIQUE KEY (USER_ID, 조상), 그것은 당신의 테이블 구조 및 / 또는 데이터에 의존 그래서 ... 또한 일치 3 번 나타나는 'ID, 잉글랜드'을 가진 사용자가없는 경우.

    SELECT user_id 
    FROM users u1
    WHERE ancestry = 'Germany'
    OR ancestry = 'France'
    OR ancestry = 'England'
    GROUP BY user_id
    HAVING count(DISTINCT ancestry) = 3
    
  5. ==============================

    5.이 질문은 몇 살입니다하지만 난 그것에 중복 통해왔다. 나도 좀 더 일반적인 솔루션을 제안합니다. 당신은 항상 조상의 고정 번호를 가지고 당신이 알고 있다면 당신은 어떤 자기가 이미 답을 제시 조인 사용할 수 있습니다. 당신이 원하는 경우 일반적인 접근 방식은 읽기 이동합니다.

    이 질문은 몇 살입니다하지만 난 그것에 중복 통해왔다. 나도 좀 더 일반적인 솔루션을 제안합니다. 당신은 항상 조상의 고정 번호를 가지고 당신이 알고 있다면 당신은 어떤 자기가 이미 답을 제시 조인 사용할 수 있습니다. 당신이 원하는 경우 일반적인 접근 방식은 읽기 이동합니다.

    당신이 여기에서 필요로하는 관계 대수의 지수라고합니다. 몫은 데카르트 제품의 다소 반전 (또는 크로스는 SQL에 가입).

    하자가 조상 세트 A는 말한다 (난 여기에 테이블 표기법을 사용, 난이 이해하기위한 좋은 생각)

    ancestry
    -----------
    'England'
    'France'
    'Germany'
    

    그리고 사용자는 U가 설정

    user_id
    --------
       1
       2
       3
    

    데카르트 제품은 C = AXU 다음이다 :

    user_id  |  ancestry
    ---------+-----------
       1     | 'England'
       1     | 'France'
       1     | 'Germany'
       2     | 'England'
       2     | 'France'
       2     | 'Germany'
       3     | 'England'
       3     | 'France'
       3     | 'Germany'
    

    그런 다음 세트 지수 U = C / A를 계산하면 얻을

    user_id
    --------
       1
       2
       3
    

    당신이 직교 제품 UXA을 다시 실행하면 다시 C를 얻을 것이다. 그러나 참고 설정된 T에 대한 (T / A) xA를 것입니다 예를 들어 반드시 재현 T., T 인 경우

    user_id  |  ancestry
    ---------+-----------
       1     | 'England'
       1     | 'France'
       1     | 'Germany'
       2     | 'England'
       2     | 'France'
    

    다음 (T / A)입니다

    user_id
    --------
       1
    

    (T / A) XA를 다음 것

    user_id  |  ancestry
    ---------+------------
       1     | 'England'
       1     | 'France'
       1     | 'Germany'
    

    USER_ID = 2에 대한 기록이 지수와 데카르트 제품 조작에 의해 제거되어 있습니다.

    귀하의 질문은 어느 USER_ID는 조상 집합의 모든 국가에서 조상을 가지고? 즉 당신은 T는 원래 세트 (또는 테이블)입니다 U는 T / A를 =합니다.

    SQL의 몫을 구현하려면 4 단계를 수행해야합니다 :

    그래서 그것을 단계적으로하자. 나는 TSQL 구문 (마이크로 소프트 SQL 서버)를 사용하지만 쉽게 다른 DBMS에 적용 할 수 있어야합니다. 테이블의 이름 (USER_ID, 조상)으로 난 조상을 선택

    CREATE TABLE ancestry_set (ancestry nvarchar(25))
    INSERT INTO ancestry_set (ancestry) VALUES ('England')
    INSERT INTO ancestry_set (ancestry) VALUES ('France')
    INSERT INTO ancestry_set (ancestry) VALUES ('Germany')
    
    CREATE TABLE ancestor ([user_id] int, ancestry nvarchar(25))
    INSERT INTO ancestor ([user_id],ancestry) VALUES (1,'England')
    INSERT INTO ancestor ([user_id],ancestry) VALUES(1,'Ireland')
    INSERT INTO ancestor ([user_id],ancestry) VALUES(2,'France')
    INSERT INTO ancestor ([user_id],ancestry) VALUES(3,'Germany')
    INSERT INTO ancestor ([user_id],ancestry) VALUES(3,'Poland')
    INSERT INTO ancestor ([user_id],ancestry) VALUES(4,'England')
    INSERT INTO ancestor ([user_id],ancestry) VALUES(4,'France')
    INSERT INTO ancestor ([user_id],ancestry) VALUES(4,'Germany')
    INSERT INTO ancestor ([user_id],ancestry) VALUES(5,'France')
    INSERT INTO ancestor ([user_id],ancestry) VALUES(5,'Germany')
    

    1) 당신의 조상 세트의 직교 제품 모든 user_ids의 집합을 만듭니다.

    SELECT a.[user_id],s.ancestry
    FROM ancestor a, ancestry_set s
    GROUP BY a.[user_id],s.ancestry
    

    2) 원래 세트에는 파트너가없는 직교 제품의 모든 레코드 찾기 (왼쪽 가입) 및

    3)) (2)의 결과 세트로부터 사용자 ID를 추출

    SELECT DISTINCT cp.[user_id]
    FROM (SELECT a.[user_id],s.ancestry
          FROM ancestor a, ancestry_set s
          GROUP BY a.[user_id],s.ancestry) cp
       LEFT JOIN ancestor a ON cp.[user_id]=a.[user_id] AND cp.ancestry=a.ancestry
    WHERE a.[user_id] is null
    

    4)) (3)의 결과 세트에 포함되지 않은 원래의 세트에서 모든 user_ids을 반환

    SELECT DISTINCT [user_id]
    FROM ancestor
    WHERE [user_id] NOT IN (
       SELECT DISTINCT cp.[user_id]
       FROM (SELECT a.[user_id],s.ancestry
             FROM ancestor a, ancestry_set s
             GROUP BY a.[user_id],s.ancestry) cp
       LEFT JOIN ancestor a ON cp.[user_id]=a.[user_id] AND cp.ancestry=a.ancestry
       WHERE a.[user_id] is null
       )
    
  6. ==============================

    6.당신이 만족하는 모든 조건임을 모든 USER_ID를 얻으려면 접근 방식 중 하나를

    당신이 만족하는 모든 조건임을 모든 USER_ID를 얻으려면 접근 방식 중 하나를

    SELECT DISTINCT user_id FROM table WHERE ancestry IN ('England', '...', '...') GROUP BY user_id HAVING count(*) = <number of conditions that has to be satisfied> 
    

    등 당신이 만족하는 적어도 하나의 조건, 당신은 할 수있는 모든 user_ids을해야하는 경우

    SELECT DISTINCT user_id from table where ancestry IN ('England', 'France', ... , '...')
    

    나는 IN 비슷한이있는 경우 인식하지 오전하지만 OR 대신에 조건을 조인

  7. ==============================

    7.브 루트 포스 (및은 오라클 시스템 테스트,하지만 난이 꽤 표준을 생각)

    브 루트 포스 (및은 오라클 시스템 테스트,하지만 난이 꽤 표준을 생각)

    select distinct usr_id from users where user_id in (
        select user_id from (
          Select user_id, Count(User_Id) As Cc
          From users 
          GROUP BY user_id
        ) Where Cc =3
      )
      and ancestry in ('England', 'France', 'Germany')
    ;
    

    편집 : 나는 더 나은 HuckIt의 대답 @있다.

  8. ==============================

    8.나는 별개로 서브 쿼리를 생성 할 수 있도록하지만, 위의 대답처럼 중복 된 기록을 가지고

    나는 별개로 서브 쿼리를 생성 할 수 있도록하지만, 위의 대답처럼 중복 된 기록을 가지고

    Select user_id
    (
       select distinct userid
       from yourtable
       where user_id = @userid
    
    ) t1
    where 
    ancestry in ('England', 'France', 'Germany')
    group by user_id
    having count(user_id) = 3
    

    이것은 내가 필요한 모든 파일을 다운로드 한 것으로 여러 기록 (다운로드 로그)이 수표를 가지고 있기 때문에 내가 사용하는 것입니다

  9. from https://stackoverflow.com/questions/7179260/sql-how-to-select-a-single-id-row-that-meets-multiple-criteria-from-a-singl by cc-by-sa and MIT license