左联接对匹配数据返回NULL

时间:2019-12-13 08:59:22

标签: sql join group-by exists snowflake-data-warehouse

我在两个表之间执行简单的LEFT JOIN

A:

YR  QTR MTH DAY        DEPT      SALES
2017 2  04  2017-04-01 B         xxxxxx
2017 1  03  2017-03-31 A         xxxxxxxx
2017 1  03  2017-03-31 B         xxxxx
2017 1  03  2017-03-30 A         xxxx

我用来带QTR_ALT号的第二张表(B)

YEAR MONTH QTR QTR_ALT
2016 12    4   12
2017 01    1   12
2017 02    1   12
2017 03    1   11
2017 04    2   11

以下LEFT JOIN B ON A.YR = B.YEAR AND A.QTR = B.QTR AND A.MTH=B.MONTH返回NULL的QTR_ALT的A.DAY BETWEEN '2016-12-01' AND '2017-03-31'

YR   QTR QTR_ALT  MTH DAY         DEPT      SALES
2017 2   11       04  2017-04-02  A         xxxxxx
2017 2   11       04  2017-04-01  A         xxxxxx
2017 2   11       04  2017-04-01  B         xxxxxx
2017 1   NULL     03  2017-03-31  A         xxxxxxxx
2017 1   NULL     03  2017-03-31  B         xxxxx
2017 1   NULL     03  2017-03-30  A         xxxx

我尝试将WHERE的条件移至JOIN,但是没有运气。即使表B中存在相应的记录,这些日期也有可能不合并?

完整代码:


    SELECT YEAR(A.DAY) as YR, 
               QUARTER(A.DAY) as QTR, 
               B.QTR_ALT, 
               (REPEAT(0, 2-LENGTH(MONTH(A.DAY))) || MONTH(A.DAY)) MTH,
               A.DAY, 
               A.DEPT, 
               SUM(A.VAL) as SALES

                FROM A
                LEFT JOIN (SELECT  TO_CHAR(ADD_MONTHS(a.DT, - b.Y), 'YYYY') as YEAR,
                                    TO_CHAR(ADD_MONTHS(a.DT, - b.Y), 'MM') as MONTH,
                                    CEIL(TO_NUMBER(TO_CHAR(add_months(a.dt, -b.y), 'MM')) / 3) as QTR,
                                    CEIL(b.y/3) as QTR_ALT

                                    FROM (SELECT TRUNC(CURRENT_DATE, 'MONTH') as DT) a
                                            CROSS JOIN (SELECT SEQ8()+1 as Y FROM TABLE(GENERATOR(ROWCOUNT => 36)) ORDER BY 1) b
                                    ORDER BY YEAR, MONTH)  B

                    ON QUARTER(A.DAY) = B.QTR 
                    AND (REPEAT(0, 2-LENGTH(MONTH(A.DAY))) || MONTH(A.DAY)) = B.MONTH


    WHERE (YEAR(A.DAY) = B.YEAR)
    AND (A.DAY BETWEEN '2016-12-01' AND '2017-03-31')
    AND A.DEPT in  ('A', 'B')

    GROUP BY A.DAY, YEAR(A.DAY),QUARTER(A.DAY),B.QTR_ALT,(REPEAT(0, 2-LENGTH(MONTH(A.DAY))) || MONTH(A.DAY)), DEPT
    ORDER BY A.DAY DESC

1 个答案:

答案 0 :(得分:1)

CREATE TEMP TABLE A (yr number, qtr number, mth text, day date, dept text, sales number);
INSERT INTO A values (2017,2,'04','2017-04-01','B', 10), 
    (2017,1,'03','2017-03-31','A', 11), 
    (2017,1,'03','2017-03-31','B', 20),
    (2017,2,'03','2017-03-30','A', 6);


WITH 
sub_b AS (
    SELECT 
        TRUNC(CURRENT_DATE, 'MONTH') AS dt,
        SEQ8() AS s, 
        ROW_NUMBER() OVER (ORDER BY s) AS y,
        ADD_MONTHS(dt, - y) as tmp_date,
        TO_CHAR(tmp_date, 'YYYY') AS year,
        --TO_CHAR(tmp_date, 'MM') AS month, -- NOT USED
        --QUARTER(tmp_date) as QTR, -- NOT USED
        CEIL(y/3) as qtr_alt -- this value seems broken
    FROM TABLE(GENERATOR(ROWCOUNT => 36))
)
SELECT a.yr, 
    a.qtr, 
    b.qtr_alt, 
    a.mth,
    a.day, 
    a.dept, 
    SUM(a.sales) AS sales
FROM a
LEFT JOIN sub_b AS b
    ON a.yr = b.year AND date_trunc('month',a.day) = b.tmp_date
WHERE a.day BETWEEN '2016-12-01' AND '2017-03-31'
    AND a.dept in ('A', 'B')
GROUP BY 1,2,3,4,5,6
ORDER BY a.day DESC;

似乎可以按照我阅读您的代码/意图的方式工作。