摆脱重复记录和计算字段

时间:2019-02-01 13:00:33

标签: sql ms-access

该帖子链接到以下内容 Sum and Substract column in same table

我在Access 2016中具有下表“ TableOfDelivery”

enter image description here

基于stackflow团队成员的帮助,我制定了一个查询

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 :(得分:1)

编辑

使用您现在在问题中提供的其他信息,我建议使用以下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 weekref的组合记录。然后,针对给定的qtyqty组合,从与其他(非最小)记录关联的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 |
+---------------+---------------+---------+

答案 1 :(得分:0)

首先,构建您的第一个查询,以过滤最小数量差异(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 here