programing

SQL: "X가 있는 모든 행 또는 없는 경우 Y가 있는 모든 행"을 얻기 위한 단일 쿼리가 있습니까?

goodsources 2023. 1. 3. 21:47
반응형

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

반응형