SQL: "X가 있는 모든 행 또는 없는 경우 Y가 있는 모든 행"을 얻기 위한 단일 쿼리가 있습니까?
"all rows where col='X'; 없으면 all rows where col='"를 얻는 방법을 알고 싶습니다.Y''
단순화된 데이터베이스
CREATE TABLE CHARACTER_NAMES(CHARACTER_ID, LANG VARCHAR(3), NAME);
INSERT INTO CHARACTER_NAMES(1, "ENG", "DONALD DUCK");
INSERT INTO CHARACTER_NAMES(1, "ENG", "GOOD OL' DONALD");
INSERT INTO CHARACTER_NAMES(1, "SWE", "KALLE ANKA");
INSERT INTO CHARACTER_NAMES(1, "SWE", "KALLEN");
INSERT INTO CHARACTER_NAMES(2, "ENG", "MICKEY MOUSE");
INSERT INTO CHARACTER_NAMES(2, "SWE", "MUSSE PIGG");
INSERT INTO CHARACTER_NAMES(2, "SWE", "MUSEN");
INSERT INTO CHARACTER_NAMES(3, "ENG", "GOOFY");
INSERT INTO CHARACTER_NAMES(3, "NOR", "FEDTMULE");
(문자가 같은 언어로 여러 개의 이름을 가진 것은 다소 강제적이지만 실제 데이터베이스는 그렇게 보입니다.또, 「CARTER_ID」도 CARTER 테이블의 외부 키이지만, 이것은 문제의 일부가 아니기 때문에 생략합니다.)
사용자는 언어 설정을 가지고 있으며, 특정 문자에 대한 데이터베이스 쿼리가 있는 경우 쿼리는 선택한 언어로 된 이름을 반환해야 합니다.또한 선택한 언어에 결과가 없는 경우에는 영어로 된 이름을 반환해야 합니다.위의 예에서 설정이 "스웨덴어"이고 사용자가 문자 3(Goofy)을 선택한 경우 스웨덴어 이름이 등록되어 있지 않으므로 이름 검색에서 "Goofy"가 반환됩니다.사용자가 미키 마우스를 선택한 경우 검색 결과 "Muse Pigg"와 "Musen"의 두 행이 반환됩니다.
SQL 쿼리로 표현할 수 있는지 궁금합니다.
선택한 언어로 FIRST를 원하는 경우(없을 경우) 다음을 사용할 수 있습니다.
SELECT NAME
FROM CHARACTER_NAMES
WHERE CHARACTER_ID=?
ORDER BY CASE
WHEN LANG='NOR' THEN 1
WHEN LANG='ENG' THEN 2
END
LIMIT 1;
하지만 선택한 언어로 이름이 몇 개 나올지 모르기 때문에 이 LIMIT을 다양하게 할 수 밖에 없고, 어떻게 하면 좋을지 잘 모르겠습니다.
"all rows where col='X'; 없으면 all rows where col='"를 얻는 방법을 알고 싶습니다.Y''
SELECT *
FROM table
WHERE col='X'
UNION ALL
SELECT *
FROM table
WHERE col='Y'
AND NOT EXISTS ( SELECT NULL
FROM table
WHERE col='X' )
행이 있는 경우col='X'
존재하면 WHERE EXISTES는 FALSE를 제공하고 두 번째 서브쿼리는 아무것도 반환하지 않습니다.즉, 첫 번째 서브쿼리의 출력만 반환됩니다.
그리고 반대로, 만약 말다툼이 없다면col='X'
그러면 첫 번째 서브쿼리는 행을 반환하지 않지만 WHERE EXISTES는 TRUE를 제공하고 두 번째 서브쿼리는 다음 값이 포함된 모든 행을 반환합니다.col='Y'
- 즉, 두 번째 서브쿼리 출력만 반환됩니다.
또는 다음을 사용할 수 있습니다.
SELECT *
FROM table
WHERE col = CASE WHEN EXISTS ( SELECT NULL
FROM table
WHERE col='X' )
THEN 'X'
ELSE 'Y'
END;
물론 더 많은 변종들이 있죠...
MySQL 8에서는CASE
과의 표현.RANK
원하는 결과를 얻으려면:
WITH cte AS (
SELECT *, RANK() OVER (PARTITION BY character_id ORDER BY CASE
WHEN lang = 'NOR' THEN 1
WHEN lang = 'ENG' THEN 2
ELSE 3
END) AS rnk
FROM character_names
)
SELECT *
FROM cte
WHERE rnk = 1
동일한 결과를 얻을 수 있습니다.NOT EXISTS
:
SELECT *
FROM character_names AS t1
WHERE lang = 'NOR'
OR lang = 'ENG' AND NOT EXISTS (
SELECT *
FROM character_names AS t2
WHERE t2.character_id = t1.character_id
AND t2.lang = 'NOR'
)
결과:
character_id | 언어 | 이름. | 인식하다 |
---|---|---|---|
1 | 엔진 | 도날드덕 | 1 |
1 | 엔진 | 굿 올 도널드 | 1 |
2 | 엔진 | 미키마우스 | 1 |
3 | 도 아니다 | FEDMULE | 1 |
언급URL : https://stackoverflow.com/questions/70288147/sql-is-there-a-single-query-to-get-all-rows-with-x-or-if-none-all-rows-with
'programing' 카테고리의 다른 글
range(start, end)에 end가 포함되지 않는 이유는 무엇입니까? (0) | 2023.01.03 |
---|---|
올바른 JSON 날짜 형식은 무엇입니까? (0) | 2023.01.03 |
Enum의 values() 메서드에 대한 문서는 어디에 있습니까? (0) | 2023.01.03 |
기존 테이블에 외부 키 추가 (0) | 2023.01.03 |
Python의 Generators와 Iterators의 차이점 (0) | 2023.01.03 |