数据子集的左连接

问题描述 投票:0回答:1

我很难描述我想要做什么,所以我认为最好只是做一个简短的例子并描述我想要实现的输出。

CREATE TABLE temp_data
(transact_dt_tm DATE
, letter CHAR(1));
CREATE TABLE temp_ref
(
letter CHAR(1)
, letter_seq INT);
INSERT INTO temp_data (transact_dt_tm,letter) VALUES (to_date('2023-01-01','YYYY-MM-DD'),'K');
INSERT INTO temp_data (transact_dt_tm,letter) VALUES (to_date('2023-01-02','YYYY-MM-DD'),'K');
INSERT INTO temp_data (transact_dt_tm,letter) VALUES (to_date('2023-01-02','YYYY-MM-DD'),'L');
INSERT INTO temp_data (transact_dt_tm,letter) VALUES (to_date('2023-01-03','YYYY-MM-DD'),'Q');
INSERT INTO temp_data (transact_dt_tm,letter) VALUES (to_date('2024-01-02','YYYY-MM-DD'),'Y');
INSERT INTO temp_data (transact_dt_tm,letter) VALUES (to_date('2024-01-03','YYYY-MM-DD'),'B');
INSERT INTO temp_ref (letter, letter_seq) values('Y',10);
INSERT INTO temp_ref (letter, letter_seq) values('B',20);
INSERT INTO temp_ref (letter, letter_seq) values('Q',30);
INSERT INTO temp_ref (letter, letter_seq) values('K',40);
INSERT INTO temp_ref (letter, letter_seq) values('L',50);

我正在选择此数据并使用热图将数据显示为网格,因此我需要 X 和 Y 类别值以及数值。在这种情况下,我的 X 将是字母,我的 Y 将是年份。我尝试过这样的事情:

SELECT
   to_char(td.transact_dt_tm,'YYYY') AS YEAR
    , tr.letter
    , count(td.TRANSACT_DT_TM)
FROM
    TEMP_DATA td
 
LEFT JOIN TEMP_REF tr ON tr.LETTER = td.LETTER 

GROUP BY 
   to_char(td.transact_dt_tm,'YYYY')
    , tr.LETTER_SEQ
    , tr.LETTER 
ORDER BY 
   to_char(td.transact_dt_tm,'YYYY')
    , tr.LETTER_SEQ;

哪个输出:

年份
2023 1
2023 K 2
2023 L 1
2024 1
2024 B 1

数据是正确的,但由于热图的生成方式,我的 X 标头不是按照我想要根据

temp_ref
表设置的顺序结束的:

年份 K L B
2023 1 2 1
2024 1 1

我想要的是我的数据像这样输出:

年份
2023
2023 B
2023 1
2023 K 2
2023 L 1
2024 1
2024 B 1

如果我这样做,我可以让这件事发生一年:

SELECT 
    tr.LETTER 
    , nvl(to_char(td.TRANSACT_DT_TM,'YYYY'),'2023') AS year
    , count(td.LETTER)
FROM 
    TEMP_REF tr 
LEFT JOIN TEMP_DATA td ON td.LETTER = tr.LETTER 
AND td.TRANSACT_DT_TM < to_date('2023-12-31','YYYY-MM-DD')
GROUP BY tr.LETTER 
    , tr.LETTER_SEQ 
    , nvl(to_char(td.TRANSACT_DT_TM,'YYYY'),'2023')
ORDER BY tr.LETTER_SEQ

但是因为第二年的数据有第一年缺失的字母,所以当我做所有年份时,

LEFT JOIN
已经满足并且不会添加缺失的字母。

我的真实数据显然比这更复杂(我有12年的交易跨越几十个“字母”)。我能想到的是,我可以使第一年像上面那样

LEFT JOINED
以获得第一年的所有字母及其序列,然后
UNION
该数据集到其余数据。有更好的方法来实现这一目标吗?谢谢!

sql oracle
1个回答
0
投票

您似乎想要一个

PARTITION
ed
OUTER JOIN
:

SELECT td.year,
       tr.letter, 
       count(td.letter)
FROM   TEMP_REF tr
       LEFT OUTER JOIN (
         SELECT EXTRACT(YEAR FROM transact_dt_tm) AS year,
                letter
         FROM   TEMP_DATA
       ) td
       PARTITION BY (td.year)
       ON tr.LETTER = td.LETTER 
GROUP BY 
       td.year,
       tr.LETTER_SEQ,
       tr.LETTER 
ORDER BY 
       td.year,
       tr.LETTER_SEQ;

对于样本数据,输出:

年份 计数(TD.字母)
2023 0
2023 B 0
2023 1
2023 K 2
2023 L 1
2024 1
2024 B 1
2024 0
2024 K 0
2024 L 0

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.