[SQL] 왼쪽에 방지 중복 값 가입
SQL왼쪽에 방지 중복 값 가입
내가 가입 왼쪽에서 중복 값을 가지고 상황에 직면했다. 나는 이것이 내가 원하는에서 원하는 동작하지만 달리있을 것 같아요.
사람, 부서 및 연락처 : 나는 세 개의 테이블이있다.
사람 :
id bigint,
person_name character varying(255)
학과 :
person_id bigint,
department_name character varying(255)
연락처 :
person_id bigint,
phone_number character varying(255)
SQL 쿼리 :
SELECT p.id, p.person_name, d.department_name, c.phone_number
FROM person p
LEFT JOIN department d
ON p.id = d.person_id
LEFT JOIN contact c
ON p.id = c.person_id;
결과 :
id|person_name|department_name|phone_number
--+-----------+---------------+------------
1 |"John" |"Finance" |"023451"
1 |"John" |"Finance" |"99478"
1 |"John" |"Finance" |"67890"
1 |"John" |"Marketing" |"023451"
1 |"John" |"Marketing" |"99478"
1 |"John" |"Marketing" |"67890"
2 |"Barbara" |"Finance" |""
3 |"Michelle" |"" |"005634"
나는 그것이 수행 조인 선택된 행에 곱하는되어 유지 무엇을 알고있다. 그러나 그것은 그들이 단지 더 큰 데이터 세트로 문제를 확대 할 필요가 반복되는 값으로 사람 존 관련된 동안 023451,99478,67890 모두 부서위한 전화 번호와 같은 감각을 준다. 그래서, 여기에 내가 원하는 것입니다 :
id|person_name|department_name|phone_number
--+-----------+---------------+------------
1 |"John" |"Finance" |"023451"
1 |"John" |"Marketing" |"99478"
1 |"John" |"" |"67890"
2 |"Barbara" |"Finance" |""
3 |"Michelle" |"" |"005634"
이것은 내 상황의 샘플 내가 테이블 및 쿼리의 큰 세트를 사용하고 있습니다. 그래서, 필요의 종류 일반적인 솔루션입니다.
해결법
-
==============================
1.나는이 문제 "크로스 프록시로 참여"를 부르는 것을 좋아합니다. 어떠한 정보 (WHERE 또는 JOIN 조건) 테이블 부서 및 연락처가 일치 해야하는 방법이 없기 때문에, 그들은 십자가에 가입 프록시 테이블 사람을 통해 수 있습니다 - 당신에게 데카르트의 제품을 제공합니다. 이것과 매우 유사합니다 :
나는이 문제 "크로스 프록시로 참여"를 부르는 것을 좋아합니다. 어떠한 정보 (WHERE 또는 JOIN 조건) 테이블 부서 및 연락처가 일치 해야하는 방법이 없기 때문에, 그들은 십자가에 가입 프록시 테이블 사람을 통해 수 있습니다 - 당신에게 데카르트의 제품을 제공합니다. 이것과 매우 유사합니다 :
더 설명이.
쿼리를위한 솔루션 :
SELECT p.id, p.person_name, d.department_name, c.phone_number FROM person p LEFT JOIN ( SELECT person_id, min(department_name) AS department_name FROM department GROUP BY person_id ) d ON d.person_id = p.id LEFT JOIN ( SELECT person_id, min(phone_number) AS phone_number FROM contact GROUP BY person_id ) c ON c.person_id = p.id;
당신은 선택 할 부서 나 전화 번호를 정의하지 않았다, 그래서 나는 임의로 최소를 선택했다. 당신은 그것을 다른 방법으로 할 수 있습니다 ...
-
==============================
2.나는 당신이 단지 특정 사람에 대한 부서의 목록과 전화를받을 필요가 있다고 생각합니다. 그러니 그냥 array_agg (또는 string_agg 또는 json_agg)를 사용합니다 :
나는 당신이 단지 특정 사람에 대한 부서의 목록과 전화를받을 필요가 있다고 생각합니다. 그러니 그냥 array_agg (또는 string_agg 또는 json_agg)를 사용합니다 :
SELECT p.id, p.person_name, array_agg(d.department_name) as "department_names", array_agg(c.phone_number) as "phone_numbers" FROM person AS p LEFT JOIN department AS d ON p.id = d.person_id LEFT JOIN contact AS c on p.id = c.person_id GROUP BY p.id, p.person_name
-
==============================
3.테이블이 분명히 논의 단순화되어 있지만, 그들이 구조적으로 결함이 나타납니다. 테이블은 엔티티 및 / 또는 속성의 목록을 엔티티 사이의 관계를 보여보다는 단지로 구성되어야한다. 그리고 전화 번호는이 경우 (개인 또는 부서 엔티티의) 속성이라고 생각합니다.
테이블이 분명히 논의 단순화되어 있지만, 그들이 구조적으로 결함이 나타납니다. 테이블은 엔티티 및 / 또는 속성의 목록을 엔티티 사이의 관계를 보여보다는 단지로 구성되어야한다. 그리고 전화 번호는이 경우 (개인 또는 부서 엔티티의) 속성이라고 생각합니다.
첫 번째 단계는 관계 테이블을 작성하는 것, 기본 키 및 가능한 외래 키를 갖는 각. 이 예에서는 사람이 테이블 사용은 기본 키 person_id로해야하는 것이 도움이 될 것이며, 부서 테이블의 기본 키 department_id 사용. 일대 다 또는 다 대다 관계, 그에 따라 외래 키를 설정하기위한 다음보기 :
한 사람을위한 테이블과 부서의 다른 테이블 : 요약하면, 만 시나리오에서 두 개의 테이블이 있어야합니다. 심지어 부서 테이블에 개인 전화 번호 (위격 테이블의 열) 및 부서 번호를 허용, 이것은 더 나은 방법이 될 것입니다.
한 부서가 많은 번호 (또는 두 개 이상의 부서 주 단일 전화 번호)를 가질 때주의해야 할 점은, 그러나 이것은 원래의 질문의 범위를 넘어서는 것입니다.
-
==============================
4.
SELECT p.id, p.person_name, d.department_name, c.phone_number FROM person p LEFT JOIN department d ON p.id = d.person_id LEFT JOIN contact c ON p.id = c.person_id group by p.id, p.person_name, d.department_name, c.phone_number
-
==============================
5.이러한 유형의 쿼리를 사용하여 SQL Server를 (당신은 당신이 그것을 원하는 각 열에 ID로 ORDER의 ID를 변경할 수 있습니다)
이러한 유형의 쿼리를 사용하여 SQL Server를 (당신은 당신이 그것을 원하는 각 열에 ID로 ORDER의 ID를 변경할 수 있습니다)
SELECT p.id, p.person_name, d.department_name, c.phone_number FROM person p LEFT JOIN (SELECT *, ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY id) AS seq FROM department) d ON d.person_id = p.id And d.seq = 1 LEFT JOIN ( SELECT *, ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY id) AS seq FROM contact) c ON c.person_id = p.id And c.seq = 1;
from https://stackoverflow.com/questions/30410622/prevent-duplicate-values-in-left-join by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL Server로 변환 MySQL의 스크립트 [마감] (0) | 2020.06.29 |
---|---|
[SQL] 대신 NULL의 어떻게 SELECT 문 SQL과 결과에 '0'표시합니까? (0) | 2020.06.29 |
[SQL] SQL Server는 열을 선택 변환 문자열로 변환 (0) | 2020.06.28 |
[SQL] 각각의 행에 대해 '어디에'조항 여러 여러 행을 업데이트 (0) | 2020.06.28 |
[SQL] 가져 오기 데이터는 두 날짜 사이에 게시 (0) | 2020.06.28 |