【问题标题】:Get rid of duplicate record and calculated field摆脱重复记录和计算字段
【发布时间】:2019-02-01 13:00:32
【问题描述】:

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

我在 access 2016 中有下表“TableOfDelivery”

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

这接近我的最终结果,但我希望得到这样的结果:
只有 3 列(见粗体框)
摆脱重复的 ref/delivery 组合(见交叉线)

非常感谢您的帮助。

我精确的计算规则:

【问题讨论】:

  • 您想要哪 3 列?另外,为什么带有负 QtyDiff 的交货周更重要?
  • 您要选择具有唯一交货周的记录吗?我说的对吗?
  • @Kars 是的,你是对的
  • 要消除重复项,您必须首先确定要保留哪些重复项,或者您是否应该首先拥有重复项,或者重复项是否表明存在错误。摆脱最后一列很容易,只需从SELECT中删除相关部分即可。
  • 正如@Arte 所说,请通过阅读minimal reproducible example 了解如何正确提问。目前你正在做的是要求我们做你的功课

标签: sql ms-access


【解决方案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 |
+---------------+---------------+---------+

这里,最里面的子查询首先获取每个delivery weekref组合的最早的reporting week记录。然后从与给定delivery weekref 组合的其他(非最小)记录相关联的qty 中减去与此最小记录相关联的qty

或者,根据您的后续 cmets 反转计算,您可以尝试以下操作:

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

【讨论】:

  • 感谢Lee Mac,结果几乎是我想要的,最后一行应该是+13。 2018-37 周报告中没有 13 件与 2018-43 年交付周相关。 13 个仅出现在 2018-41 报告周,2018-43 交付周
  • @AndyK 你可能是对的......我只是无法抗拒编码挑战。
  • 我也是@LeeMac,但我们还需要树立正确的榜样,否则新人会说 SO 不是一个受欢迎的地方。很受欢迎,只要我们对规则有共同的理解?
  • @AndyK 我同意并且可以看到这样的问题会如何导致其他刚接触该网站的人错误地认为 SO 是一个会员很乐意为您编写代码的地方。当然,这个网站上的许多其他答案也将为 OP 提供一个完整的解决方案,尽管涉及的代码行数要少得多,它看起来不像“工作”。
  • @Lee Mac,我按照约定做了。
【解决方案2】:

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

【讨论】:

  • 谢谢。我尝试运行查询,但出现错误。我认为是由于您告诉我在某个地方替换的 TableOfDelivery。你能澄清一下吗?
猜你喜欢
  • 1970-01-01
  • 2015-01-12
  • 1970-01-01
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
相关资源
最近更新 更多