Избавьтесь от дубликата записи и рассчитанного поля - PullRequest
0 голосов
/ 01 февраля 2019

Сообщение связано со следующим столбцом Сумма и Субстратура в той же таблице

У меня есть следующая таблица "TableOfDelivery" в доступе 2016

enter image description here

Основываясь на помощи члена команды стека потока, я разработал запрос

SELECT t1.ref, t1.[delivery week], (t2.qty-t1.qty) AS QtyDiff, iif(t1.[delivery week] <> t1.[delivery week],t1.qty *-1, t1.qty) AS Diff
FROM TableOfDelivery AS t1 LEFT JOIN TableOfDelivery AS t2 ON (t1.[delivery week] = t2.[delivery week]
AND (t1.[reporting week] <> t2.[reporting week])) AND (t1.ref = t2.ref)
GROUP BY t1.[reporting week], t1.ref, t1.[delivery week], (t2.qty-t1.qty), t1.qty
ORDER BY t1.[reporting week];

enter image description here

Это близко к моему окончательному результату, но я хотел бы получить эторезультат:
Только 3 столбца (см. выделенную рамку)
Избавьтесь от дублирующейся комбинации реф / доставка (см. пересекающиеся линии)

enter image description here

Я был бы очень признателен вамсправка.

Я заранее уточнил правила расчета: enter image description here

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

РЕДАКТИРОВАТЬ

С учетом дополнительной информации, которую вы теперь предоставили в своем вопросе, я бы предложил следующий SQL:

select 
    t0.ref, 
    t0.[delivery week], 
    nz(t3.q1,0) - nz(t6.q2,0) as QtyDiff
from
    (
        tableofdelivery t0
        left join
        (
             select 
                t1.ref, t1.[delivery week], sum(t1.qty) as q1
             from 
                tableofdelivery t1
             where 
                t1.[reporting week] = 
                (
                    select max(t2.[reporting week]) 
                    from tableofdelivery t2 
                    where t2.ref = t1.ref
                )
             group by 
                t1.ref, t1.[delivery week]
        ) t3 on t0.ref = t3.ref and t0.[delivery week] = t3.[delivery week]
    ) left join
    (
        select 
            t4.ref, t4.[delivery week], sum(t4.qty) as q2
        from 
            tableofdelivery t4
        where 
            t4.[reporting week] < 
            (
                select max(t5.[reporting week]) 
                from tableofdelivery t5 
                where t5.ref = t4.ref
            )
        group by 
            t4.ref, t4.[delivery week]
    ) t6 on t0.ref = t6.ref and t0.[delivery week] = t6.[delivery week]
group by 
    t0.ref, t0.[delivery week], nz(t3.q1,0) - nz(t6.q2,0)

Оригинальный ответ

ПредполагаяЯ правильно понял результат, который вы хотите получить, я бы предложил следующий код:

select 
    t0.ref, 
    t0.[delivery week], 
    nz(t2.qty, 0) - t0.qty as qtydiff
from
    (
        tableofdelivery t0 inner join
        (
            select t.ref, t.[delivery week] as dw, min(t.[reporting week]) as rw
            from tableofdelivery t
            group by t.ref, t.[delivery week]
        ) t1 on 
        t0.ref = t1.ref and 
        t0.[delivery week]  = t1.dw and 
        t0.[reporting week] = t1.rw
    )
    left join tableofdelivery t2 on 
    t1.ref = t2.ref and 
    t1.dw = t2.[delivery week] and 
    t1.rw <> t2.[reporting week]
order by
    t0.ref, 
    t0.[delivery week]

Который, для ваших предоставленных образцов данных:

+----------------+---------------+---------------+-----+
| reporting week |      ref      | delivery week | qty |
+----------------+---------------+---------------+-----+
| 2018-37        | DTR0000182433 | 2018-31       |  19 |
| 2018-41        | DTR0000182433 | 2018-31       |  20 |
| 2018-37        | DTR0000182433 | 2018-33       |  50 |
| 2018-41        | DTR0000182433 | 2018-33       |  13 |
| 2018-37        | DTR0000182433 | 2018-35       |  50 |
| 2018-37        | DTR0000182433 | 2018-39       | 100 |
| 2018-41        | DTR0000182433 | 2018-43       |  13 |
+----------------+---------------+---------------+-----+

Получает следующеерезультат:

+---------------+---------------+---------+
|      ref      | delivery week | qtydiff |
+---------------+---------------+---------+
| DTR0000182433 | 2018-31       |       1 |
| DTR0000182433 | 2018-33       |     -37 |
| DTR0000182433 | 2018-35       |     -50 |
| DTR0000182433 | 2018-39       |    -100 |
| DTR0000182433 | 2018-43       |     -13 |
+---------------+---------------+---------+

Здесь самый внутренний подзапрос сначала получает самую раннюю запись reporting week для каждой комбинации delivery week и ref.qty, связанный с этой минимальной записью, затем вычитается из qty, связанной с другими (не минимальными) записями для данной комбинации delivery week и ref.

В качестве альтернативы, обратное вычислениеосновываясь на ваших последующих комментариях, вы можете попробовать следующее:

select 
    t0.ref, 
    t0.[delivery week], 
    t0.qty - nz(t2.qty, 0) as qtydiff
from
    (
        tableofdelivery t0 inner join
        (
            select t.ref, t.[delivery week] as dw, max(t.[reporting week]) as rw
            from tableofdelivery t
            group by t.ref, t.[delivery week]
        ) t1 on 
        t0.ref = t1.ref and 
        t0.[delivery week]  = t1.dw and 
        t0.[reporting week] = t1.rw
    )
    left join tableofdelivery t2 on 
    t1.ref = t2.ref and 
    t1.dw = t2.[delivery week] and 
    t1.rw > t2.[reporting week]
order by
    t0.ref, 
    t0.[delivery week]

Что для предоставленных вами образцов данных:

+----------------+---------------+---------------+-----+
| reporting week |      ref      | delivery week | qty |
+----------------+---------------+---------------+-----+
| 2018-37        | DTR0000182433 | 2018-31       |  19 |
| 2018-41        | DTR0000182433 | 2018-31       |  20 |
| 2018-37        | DTR0000182433 | 2018-33       |  50 |
| 2018-41        | DTR0000182433 | 2018-33       |  13 |
| 2018-37        | DTR0000182433 | 2018-35       |  50 |
| 2018-37        | DTR0000182433 | 2018-39       | 100 |
| 2018-41        | DTR0000182433 | 2018-43       |  13 |
+----------------+---------------+---------------+-----+

Дает следующий результат:

+---------------+---------------+---------+
|      ref      | delivery week | qtydiff |
+---------------+---------------+---------+
| DTR0000182433 | 2018-31       |       1 |
| DTR0000182433 | 2018-33       |     -37 |
| DTR0000182433 | 2018-35       |      50 |
| DTR0000182433 | 2018-39       |     100 |
| DTR0000182433 | 2018-43       |      13 |
+---------------+---------------+---------+
0 голосов
/ 02 февраля 2019

Сначала создайте свой первый запрос, чтобы отфильтровать минимальную количественную разницу (qtydiff).Для ясности я использовал TableOfDelivery, чтобы подвести итог начального запроса, который вы задали выше.Вам нужно будет заменить TableOfDelivery на ваш запрос, чтобы он работал.

Запрос 1

Я поставил deliveryweek вместо [Delivery Week].Вам нужно будет изменить его обратно на [Delivery Week].Я сделал это так, как мне было проще, для целей тестирования.

    SELECT  a.*
FROM    TableOfDelivery AS  a
    INNER JOIN
    (
        SELECT deliveryweek, MIN(qtydiff) AS "min_qty_diff"      
      FROM TableOfDelivery 
        GROUP BY deliveryweek
    ) AS b
        ON a.deliveryweek = b.deliveryweek
        AND a.qtydiff  = b.min_qty_diff

Однако в качестве первого фильтра необходимо также убедиться, что разница (diff) также минимальна, поскольку, возможно, есть равные различия.Поместите приведенный выше запрос (запрос 1) в подзапрос

SELECT 
 sub_query.ref,
 sub_query.deliveryweek,
 sub_query.qtydiff,
 MIN(sub_query.diff)
FROM 
(the query above) AS sub_query
GROUP BY 
    sub_query.ref,
    sub_query.deliveryweek,
    sub_query.qtydiff

, который даст вам окончательный результат

    SELECT 
    sub_query.ref,
    sub_query.deliveryweek,
    sub_query.qtydiff,
    MIN(sub_query.diff)
FROM 
(
SELECT  a.*
FROM    TableOfDelivery AS  a
    INNER JOIN
    (
        SELECT deliveryweek, MIN(qtydiff) AS "min_qty_diff"
      --, MIN(diff) AS "min_diff"       
      FROM TableOfDelivery 
        GROUP BY deliveryweek
    ) AS b
        ON a.deliveryweek = b.deliveryweek
        AND a.qtydiff  = b.min_qty_diff
) as sub_query
GROUP BY 
    sub_query.ref,
    sub_query.deliveryweek,
    sub_query.qtydiff
;

SQL Fiddle здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...