【问题标题】:distinct id from current month to previous month & missing id from previous month to current month从当月到上月的不同ID和从上月到当月的缺失ID
【发布时间】:2019-06-27 22:07:27
【问题描述】:

我正在尝试获取当前月份与上个月相比的不同 ID,以及从上个月到当前月份不同的缺失 ID。我有一个表,其中有两个字段,即快照名称和 assetsrcsysid。我已经加载了 201901、201902 和 201812 的样本数据。理想情况下,我的这些数据可以追溯到 201401,但对于试验,我使用 3 个月的数据进行此操作。

请建议我如何改进此查询,使其包括可追溯到 201401 的所有月份。

我使用下面的查询来获取快照名称,incoming_sysid(在本月是新的,在上个月不存在)和传出_sysid(在本月的上个月中缺失)如下。我在 windows 7 64 位平台上使用 PostgreSQL 运行了这个查询。

WITH incoming AS
  (SELECT snapshotname,
          count(DISTINCT assetsrcsysid) AS incoming_sysid
   FROM public.sampleassetsrcsysid
   WHERE snapshotname = '201901'
     AND assetsrcsysid NOT IN
       (SELECT assetsrcsysid
        FROM public.sampleassetsrcsysid
        WHERE snapshotname = '201812' )
   GROUP BY snapshotname),

     outgoing AS
  (SELECT snapshotname,
          count(DISTINCT assetsrcsysid) AS outgoing_sysid
   FROM public.sampleassetsrcsysid
   WHERE snapshotname = '201812'
     AND assetsrcsysid NOT IN
       (SELECT assetsrcsysid
        FROM public.sampleassetsrcsysid
        WHERE snapshotname = '201901' )
   GROUP BY snapshotname)

SELECT incoming.snapshotname,
       incoming.incoming_sysid,
       outgoing.outgoing_sysid
FROM incoming,
     outgoing
WHERE 1=1;

预期结果:

snapshotname  incoming_sysid  outgoing_sysid
201902          4               3
201901          3               5

虚拟数据:

snapshotname    assetsrcsysid
201901  s1
201901  s2
201901  s3
201901  s4
201901  s5
201901  s6
201901  s15
201812  s1
201812  s2
201812  s3
201812  s4
201812  s7
201812  s9
201812  s10
201812  s11
201812  s12
201902  s1
201902  s2
201902  s3
201902  s13
201902  s17
201902  s19
201902  s20
201902  s5

enter image description here

【问题讨论】:

  • 假设 assetsrcsysid 第一次存在于 201801,然后不在 201802 和 201803 中,而是在 201804 中再次存在。这是否可能或者消失的 assetsrcsysid 永远不会再次出现?如果它可以重新出现:我是否会将其视为 201804 的传入,因为它在 201803 中不存在?或者我不会计算它,因为它存在于前一个月(在我的示例中为 201801)?
  • 另一个问题:如果一个assetsrcsysid只存在一个月,那我算当月的传入和传出,对吗?

标签: sql postgresql


【解决方案1】:

假设我正确理解了您的问题,我会采用完全不同的方法,使用窗口函数。这从两件事开始:

  • 每个snapshotnameassetsrcsysid 都有一条记录,这样可以更轻松地使用窗口函数。
  • 句点的枚举,因此它们只是数字。

然后我们可以使用lead()lag()来判断给定的assetsrcsysid是在下个月还是上个月,大大简化了查询:

with s as (
      select s.*,
             dense_rank() over (order by snapshotname) as snapshotname_index
      from (select distinct snapshotname, assetsrcsysid
            from public.sampleassetsrcsysid s
           ) s
     )
select snapshotname,
       sum( (prev_snapshotname_index = snapshotname_index - 1)::int ) as num_incoming,
       sum( (next_snapshotname_index = snapshotname_index + 1)::int ) as num_outcoming
from (select s.*,
             lag(snapshotname_index) over (partition by assetsrcsysid order by assetsrcsysid) as prev_snapshotname_index,
             lead(snapshotname_index) over (partition by assetsrcsysid order by assetsrcsysid) as next_snapshotname_index
      from s
     ) s
group by snapshotname
order by snapshotname;

【讨论】:

  • 感谢您对此的快速回复。我明白你在说什么,但似乎查询的框架方式,我无法得到预期的结果。我尝试在这里调整领先和滞后窗口功能。让我在我的原始帖子中添加 3 个月的示例数据(201902、201901 和 201812)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-24
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多