我很难描述我想要做什么,所以我认为最好只是做一个简短的例子并描述我想要实现的输出。
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
该数据集到其余数据。有更好的方法来实现这一目标吗?谢谢!
您似乎想要一个
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 |