Запрос DB2 с подзапросами и несколькими группами по операторам - PullRequest
0 голосов
/ 25 января 2019

У меня есть запрос с несколькими подзапросами и условиями для построения вычисляемых столбцов, каждый из которых имеет свою собственную группировку.

Проблема в том, что что-то не присоединено или сгруппировано правильно, и я не могу получить правильные значения во всех строках. Я выбираю необработанные строки за последние 90 дней, но мои расчеты основаны только на записях за последние 30 дней.

SELECT
  t.dealer,
  t.rep,
  t.group,
  t.dtl1,
  t.dtl2,
  t.quant,
  temp.sales as V1,
  tmng.sales as V2,
  tall.sales as V3
FROM
     products t
    left outer JOIN (
        SELECT dealer,group,dtl1,dtl2, SUM(cast(quant as int)) as sales
        FROM products
        WHERE last_ship_date > CURRENT_DATE - 30 DAYS
        GROUP BY dealer,group,dtl1,dtl2
    ) temp ON temp.dealer = t.dealer and temp.group = t.group and temp.dtl1 = t.dtl1 and temp.dtl2 = t.dtl2
    left outer JOIN (
        SELECT sales_rep, group,dtl1,dtl2, SUM(cast(quant as int)) as sales
        FROM products
        WHERE last_ship_date > CURRENT_DATE - 30 DAYS
        GROUP BY sales_rep,group,dtl1,dtl2
    ) tmng ON  tmng.sales_rep = t.sales_rep AND tmng.group = t.group AND tmng.dtl1 = t.dtl1 and tmng.dtl2 = t.dtl2
    left outer JOIN (
        SELECT dealer, sales_rep, group,dtl1,dtl2,SUM(cast(quant as int)) as sales
        FROM products
        WHERE last_ship_date > CURRENT_DATE - 30 DAYS
        group by dealer,sales_rep, group,dtl1,dtl2
    ) tall on tall.dealer = t.dealer and tall.sales_rep = t.sales_rep and  tall.group = t.group and tall.dtl1 = t.dtl1 and tall.dtl2 = t.dtl2

WHERE t.last_ship_date > CURRENT_DATE - 90 DAYS;

Идея заключается в том, что продукт является уникальным для Group / Dtl1 / Dtl2. Поэтому, если я сделаю запрос по одному продукту (с этой уникальной комбинацией), я получу конкретное общее количество в строке, но мне нужно разрешить мои последние три столбца, где мне нужна сумма 'qty' за последние 30 дней для дилер, рэп и итого.

Прямо сейчас я получаю правильное количество строк, но точечные значения и значения NULL в моих последних трех столбцах.

Dealer | Rep   | Group  | Dtl1   | Dtl2 | qty |   V1  |   V2    |  V3
========================================================================
21177  |  165  |  4867  |  2878  |  29  |  1  |  null  |  null  |  null
19445  |  182  |  4867  |  2878  |  29  |  1  |  null  |  null  |  null
20949  |  340  |  4867  |  2878  |  29  |  2  |  null  |  null  |  null
21347  |  353  |  4867  |  2878  |  29  |  1  |  null  |  null  |  null
23068  |  353  |  4867  |  2878  |  29  |  1  |  null  |  null  |  null
17195  |  353  |  4867  |  2878  |  29  |  6  |  null  |  null  |  null
23040  |  353  |  4867  |  2878  |  29  |  1  |  null  |  null  |  null
5620   |  380  |  4867  |  2878  |  29  |  4  |  null  |  null  |  null
23009  |  380  |  4867  |  2878  |  29  |  3  |  null  |  null  |  null
13529  |  390  |  4867  |  2878  |  29  |  1  |  null  |  null  |  null
22706  |  394  |  4867  |  2878  |  29  |  1  |  1     |  1     |  1
17049  |  394  |  4867  |  2878  |  29  |  4  |  1     | null   | null 
17879  |  397  |  4867  |  2878  |  29  |  1  |  null  |  null  |  null
21320  |  445  |  4867  |  2878  |  29  |  1  |  null  |  null  |  null
21231  |  457  |  4867  |  2878  |  29  |  1  |  1     |  1     |  1

То, что я пытаюсь получить, это:

Dealer | Rep   | Group  | Dtl1   | Dtl2 | qty | V1  | V2  |  V3
================================================================
21177  |  165  |  4867  |  2878  |  29  |  1  |  1  |  1  |  29
19445  |  182  |  4867  |  2878  |  29  |  1  |  1  |  1  |  29
20949  |  340  |  4867  |  2878  |  29  |  2  |  2  |  2  |  29
21347  |  353  |  4867  |  2878  |  29  |  1  |  1  |  9  |  29
23068  |  353  |  4867  |  2878  |  29  |  1  |  1  |  9  |  29
17195  |  353  |  4867  |  2878  |  29  |  6  |  6  |  9  |  29
23040  |  353  |  4867  |  2878  |  29  |  1  |  1  |  9  |  29
5620   |  380  |  4867  |  2878  |  29  |  4  |  4  |  7  |  29
23009  |  380  |  4867  |  2878  |  29  |  3  |  3  |  7  |  29
13529  |  390  |  4867  |  2878  |  29  |  1  |  1  |  1  |  29
22706  |  394  |  4867  |  2878  |  29  |  1  |  1  |  5  |  29
17049  |  394  |  4867  |  2878  |  29  |  4  |  4  |  5  |  29 
17879  |  397  |  4867  |  2878  |  29  |  1  |  1  |  1  |  29
21320  |  445  |  4867  |  2878  |  29  |  1  |  1  |  1  |  29
21231  |  457  |  4867  |  2878  |  29  |  1  |  1  |  1  |  29

Таким образом, V1 - это сумма кол-во для дилера / группы / dtl1 / dtl2 за последние 30 дней, V2 - это сумма кол-во для Rep / Group / Dtl1 / Dtl2 за последние 30 дней, а V3 - это ИТОГО сумма (кол-во) для этой группы / Dtl1 / Dtl2 за последние 30 дней.

Что я не так делаю?

Вот скрипка: http://www.sqlfiddle.com/#!9/22251a

1 Ответ

0 голосов
/ 25 января 2019

Попробуйте это:

WITH T (DEALER, REP, GROUP, DTL1, Dtl2, QUANT, LAST_SHIP_DATE) AS (
VALUES  (21177, 165, 4867, 2878, 29, 1, CURRENT DATE - 10 DAY),
        (19445, 182, 4867, 2878, 29, 1, CURRENT DATE - 10 DAY),
        (20949, 340, 4867, 2878, 29, 2, CURRENT DATE - 10 DAY),
        (21347, 353, 4867, 2878, 29, 1, CURRENT DATE - 10 DAY),
        (23068, 353, 4867, 2878, 29, 1, CURRENT DATE - 10 DAY),
        (17195, 353, 4867, 2878, 29, 6, CURRENT DATE - 10 DAY),
        (23040, 353, 4867, 2878, 29, 1, CURRENT DATE - 10 DAY),
        (5620,  380, 4867, 2878, 29, 4, CURRENT DATE - 10 DAY),
        (23009, 380, 4867, 2878, 29, 3, CURRENT DATE - 10 DAY),
        (13529, 390, 4867, 2878, 29, 1, CURRENT DATE - 10 DAY),
        (22706, 394, 4867, 2878, 29, 1, CURRENT DATE - 10 DAY),
        (17049, 394, 4867, 2878, 29, 4, CURRENT DATE - 10 DAY),
        (17879, 397, 4867, 2878, 29, 1, CURRENT DATE - 10 DAY),
        (21320, 445, 4867, 2878, 29, 1, CURRENT DATE - 10 DAY),
        (21231, 457, 4867, 2878, 29, 1, CURRENT DATE - 10 DAY)
      , (1, 1, 4867, 2878, 29, 1, CURRENT DATE - 100 DAY)
)
SELECT T.DEALER, T.REP, T.GROUP, T.DTL1, T.Dtl2, T.QUANT
/*
, SUM(CASE WHEN last_ship_date > CURRENT_DATE - 30 DAYS THEN QUANT END) OVER(PARTITION BY DEALER, GROUP, DTL1, Dtl2) V1
, SUM(CASE WHEN last_ship_date > CURRENT_DATE - 30 DAYS THEN QUANT END) OVER(PARTITION BY REP,    GROUP, DTL1, Dtl2) V2
, SUM(CASE WHEN last_ship_date > CURRENT_DATE - 30 DAYS THEN QUANT END) OVER(PARTITION BY         GROUP, DTL1, Dtl2) V3
FROM T;
*/
, COALESCE(T1.V1, 0) V1, COALESCE(T2.V2, 0) V2, COALESCE(T3.V3, 0) V3
FROM T
LEFT JOIN (
SELECT DEALER, GROUP, DTL1, Dtl2, SUM(QUANT) V1
FROM T
WHERE last_ship_date > CURRENT_DATE - 30 DAYS
GROUP BY DEALER, GROUP, DTL1, Dtl2
) T1 ON T1.DEALER=T.DEALER AND T1.GROUP=T.GROUP AND T1.DTL1=T.DTL1 AND T1.DTL2=T.DTL2
LEFT JOIN (
SELECT REP, GROUP, DTL1, Dtl2, SUM(QUANT) V2
FROM T
WHERE last_ship_date > CURRENT_DATE - 30 DAYS
GROUP BY REP, GROUP, DTL1, Dtl2
) T2 ON T2.REP=T.REP AND T2.GROUP=T.GROUP AND T2.DTL1=T.DTL1 AND T2.DTL2=T.DTL2
LEFT JOIN (
SELECT GROUP, DTL1, Dtl2, SUM(QUANT) V3
FROM T
WHERE last_ship_date > CURRENT_DATE - 30 DAYS
GROUP BY GROUP, DTL1, Dtl2
) T3 ON T3.GROUP=T.GROUP AND T3.DTL1=T.DTL1 AND T3.DTL2=T.DTL2;
...