source

이 케이스가 NULL을 반환하는 이유는 무엇입니까?

lovecheck 2022. 10. 30. 17:58
반응형

이 케이스가 NULL을 반환하는 이유는 무엇입니까?

이와 같은 선택 쿼리를 사용하여 어떤 날짜가 최신 날짜(dtStart)인지, 어떤 테이블에서 최신 날짜가 왔는지(TableOrigin) 알 수 있습니다.

WITH ranked_entity AS (
 SELECT
    table5.id,
    GREATEST(
        COALESCE(table1.dtEvaluationStart, '0000-00-00 00:00:00'), 
        COALESCE(table2.dtStart, '0000-00-00 00:00:00'), 
        COALESCE(table3.dtEvaluationStart, '0000-00-00 00:00:00'),
        COALESCE(table4.dtStart, '0000-00-00 00:00:00')) as dtStart,
    CASE GREATEST(
        COALESCE(table1.dtEvaluationStart, '0000-00-00 00:00:00'), 
        COALESCE(table2.dtStart, '0000-00-00 00:00:00'), 
        COALESCE(table3.dtEvaluationStart, '0000-00-00 00:00:00'),
        COALESCE(table4.dtStart, '0000-00-00 00:00:00')
        )
    WHEN table1.dtEvaluationStart THEN 'table1'
    WHEN table2.dtStart THEN 'table2'
    WHEN table3.dtEvaluationStart THEN 'table3'
    WHEN table4.dtStart THEN 'table4'
    END AS TableOrigin,
    ROW_NUMBER() OVER (PARTITION BY id ORDER BY dtStart DESC) AS rn
 FROM table5 
    LEFT JOIN table1 ON table5.id = table1.fid 
    LEFT JOIN table2 ON table5.id = table2.fid
    LEFT JOIN table3 ON table5.id = table3.fid 
    LEFT JOIN table4 ON table5.id = table4.fid
)
    SELECT * FROM ranked_entity WHERE rn = 1;

단, dtStart가 설정되어 있어도 TableOrigin이 NULL일 수 있습니다.왜 그렇죠?

예를 들어 dtStart 열의 값은 4개의 테이블 열 중 가장 최신 날짜이므로 table3에서 가져온 값 '2020-05-14 14:34:18'입니다.즉, TableOrigin 열에 이 행의 값 'table3'이 있어야 합니다.대신 TableOrigin은 NULL입니다.이것은 모든 행에서 발생하는 것은 아닙니다.일부 행에서는 TableOrigin 값이 정확합니다.

샘플 데이터:

table5
+-----+
| id  |
+-----+
| 198 |
| 197 |
+-----+

table1
+-----+---------------------+
| fid |  dtEvaluationStart  |
+-----+---------------------+
| 198 | 2018-01-11 13:59:17 |
| 197 | 2020-01-21 09:29:35 |
+-----+---------------------+

table2
+-----+---------------------+
| fid |       dtStart       |
+-----+---------------------+
| 198 | 2018-02-01 12:57:50 |
| 197 | 2020-11-18 10:14:31 |
+-----+---------------------+

table3
+-----+---------------------+
| fid |       dtStart       |
+-----+---------------------+
| 197 | 2018-01-10 14:58:19 |
+-----+---------------------+

table4
+-----+---------------------+
| fid |       dtStart       |
+-----+---------------------+
| 198 | 2020-03-01 09:40:09 |
| 197 | 2020-03-04 08:10:59 |
+-----+---------------------+

output
+-----+---------------------+-------------+
| id  |       dtStart       | TableOrigin |
+-----+---------------------+-------------+
| 198 | 2020-03-01 09:40:09 | NULL        |
| 197 | 2020-11-18 10:14:31 | table2      |
+-----+---------------------+-------------+

MySql에서는 정상적으로 동작하지만 MariaDB에서는 동작하지 않습니다.
회피책으로서 반복할 수 있습니다.COALESCE()당신의 안에서CASE식:

WITH ranked_entity AS (
 SELECT
    table5.id,
    GREATEST(
        COALESCE(table1.dtEvaluationStart, '0000-00-00 00:00:00'), 
        COALESCE(table2.dtStart, '0000-00-00 00:00:00'), 
        COALESCE(table3.dtEvaluationStart, '0000-00-00 00:00:00'),
        COALESCE(table4.dtStart, '0000-00-00 00:00:00')) as dtStart,
    CASE GREATEST(
        COALESCE(table1.dtEvaluationStart, '0000-00-00 00:00:00'), 
        COALESCE(table2.dtStart, '0000-00-00 00:00:00'), 
        COALESCE(table3.dtEvaluationStart, '0000-00-00 00:00:00'),
        COALESCE(table4.dtStart, '0000-00-00 00:00:00')
        )
    WHEN COALESCE(table1.dtEvaluationStart, '0000-00-00 00:00:00') THEN 'table1'
    WHEN COALESCE(table2.dtStart, '0000-00-00 00:00:00') THEN 'table2'
    WHEN COALESCE(table3.dtEvaluationStart, '0000-00-00 00:00:00') THEN 'table3'
    WHEN COALESCE(table4.dtStart, '0000-00-00 00:00:00') THEN 'table4'
    END AS TableOrigin,
    ROW_NUMBER() OVER (PARTITION BY table5.id ORDER BY table4.dtStart DESC) AS rn
 FROM table5 
    LEFT JOIN table1 ON table5.id = table1.fid 
    LEFT JOIN table2 ON table5.id = table2.fid
    LEFT JOIN table3 ON table5.id = table3.fid 
    LEFT JOIN table4 ON table5.id = table4.fid
)
SELECT * FROM ranked_entity WHERE rn = 1;

데모를 참조해 주세요.
결과:

>  id | dtStart             | TableOrigin | rn
> --: | :------------------ | :---------- | -:
> 197 | 2020-11-18 10:14:31 | table2      |  1
> 198 | 2020-03-01 09:40:09 | table4      |  1

dstart항상 설정됩니다.단, 값이 다음과 같은 경우'0000-00-00 00:00:00'비교되는 모든 값은 (가능하게)NULL상수 값이 일치하지 않습니다.NULL열 이름이 일치하지 않습니다.

NULLvalue는 이것을 나타내고 있습니다.

너도 원한다면dtstart되려고NULL이 경우, 사용NULLIF():

NULLIF(GREATEST(COALESCE(table1.dtEvaluationStart, '0000-00-00 00:00:00'), 
                COALESCE(table2.dtStart, '0000-00-00 00:00:00'), 
                COALESCE(table3.dtEvaluationStart, '0000-00-00 00:00:00'),
                COALESCE(table4.dtStart, '0000-00-00 00:00:00')
               ), '0000-00-00 00:00:00'
      )

언급URL : https://stackoverflow.com/questions/65108118/why-is-this-case-greatest-returning-null

반응형