Get rid of duplicate record and calculated field

不羁的心 提交于 2019-12-25 18:43:00

问题


The post is linked to the following Sum and Substract column in same table

I’ve the following table "TableOfDelivery" in access 2016

Based on stackflow team member help, I worked out a query

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];

This is close to my final outcome but I would like to have this result:
Only 3 columns (see bold box)
Get rid off the duplicate ref/delivery combination (see crossed lines)

I would very appreciate your help.

I précised the calculation rules:


回答1:


EDIT

With the additional information you have now provided in your question, I would suggest the following 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)

Original Answer

Assuming I've correctly understood the result that you are looking to obtain, I would suggest the following code:

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]

Which, for your supplied sample data:

+----------------+---------------+---------------+-----+
| 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 |
+----------------+---------------+---------------+-----+

Yields the following result:

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

Here, the innermost subquery first obtains the earliest reporting week record for each delivery week and ref combination. The qty associated with this minimum record is then subtracted from the qty associated with the other (non-minimum) records for the given delivery week and ref combination.

Alternatively, reversing the calculation based on your subsequent comments, you could try the following:

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]

Which, for your supplied sample data:

+----------------+---------------+---------------+-----+
| 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 |
+----------------+---------------+---------------+-----+

Yields the following result:

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



回答2:


First, build your first query as a way to filter the minimal quantity difference (qtydiff). For reading clarity, I've used TableOfDelivery to summarize the inital query, the one you've put above. You will need to replace TableOfDelivery with your query, to make it work.

Query 1

I've put deliveryweek, instead of [Delivery Week]. You will need to change it back to [Delivery Week]. I did it as it was easier for me, for testing purpose.

    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

However, as first filter, you need to make also sure that the difference (diff) is also minimal as there maybe equal differences. Put the query above (Query 1) into a subquery

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

Which gives you the final result

    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 here



来源:https://stackoverflow.com/questions/54480089/get-rid-of-duplicate-record-and-calculated-field

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!