【问题标题】:SQL - Summary of transactions - Calculate start end time of transactions based on columnSQL - 事务摘要 - 根据列计算事务的开始结束时间
【发布时间】:2019-11-15 21:29:42
【问题描述】:

我有一个 SQL 表,其中保存了机器每分钟的产品交易和包装产品的累计总数。

我正在尝试将此表(在 sql 查询中)汇总到产品运行中。

  • 开始时间由累积大于0的产品的第一条记录表示
  • 完成时间由产品运行的最后一条记录表示 - 但如果累计没有变化(即实际包装的产品不再存在)则忽略
  • 如示例表中所示,同一产品一天可以运行多次,但摘要应显示每个单独的产品运行。

创建表并插入数据....

CREATE TABLE [dbo].[Test](
    [ID] [nchar](10) NULL,
    [Product] [varchar](20) NULL,
    [datetime] [datetime] NULL,
    [Cumulative_Packed] [int] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'1         ', N'Item1', CAST(N'2019-11-14T14:15:00.000' AS DateTime), 10)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'2         ', N'Item1', CAST(N'2019-11-14T14:16:00.000' AS DateTime), 22)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'3         ', N'Item1', CAST(N'2019-11-14T14:17:00.000' AS DateTime), 35)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'4         ', N'Item1', CAST(N'2019-11-14T14:18:00.000' AS DateTime), 40)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'5         ', N'Item1', CAST(N'2019-11-14T14:19:00.000' AS DateTime), 40)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'6         ', N'Item1', CAST(N'2019-11-14T14:20:00.000' AS DateTime), 40)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'7         ', N'Item1', CAST(N'2019-11-14T14:21:00.000' AS DateTime), 0)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'8         ', N'Item1', CAST(N'2019-11-14T14:22:00.000' AS DateTime), 0)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'9         ', N'Item1', CAST(N'2019-11-14T14:23:00.000' AS DateTime), 0)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'10        ', N'Item2', CAST(N'2019-11-14T14:24:00.000' AS DateTime), 12)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'11        ', N'Item2', CAST(N'2019-11-14T14:25:00.000' AS DateTime), 18)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'12        ', N'Item2', CAST(N'2019-11-14T14:26:00.000' AS DateTime), 18)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'13        ', N'Item2', CAST(N'2019-11-14T14:27:00.000' AS DateTime), 22)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'14        ', N'Item2', CAST(N'2019-11-14T14:28:00.000' AS DateTime), 22)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'15        ', N'Item1', CAST(N'2019-11-14T14:29:00.000' AS DateTime), 0)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'16        ', N'Item1', CAST(N'2019-11-14T14:30:00.000' AS DateTime), 7)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'17        ', N'Item1', CAST(N'2019-11-14T14:31:00.000' AS DateTime), 30)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'18        ', N'Item1', CAST(N'2019-11-14T14:32:00.000' AS DateTime), 38)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'19        ', N'Item1', CAST(N'2019-11-14T14:33:00.000' AS DateTime), 38)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'20        ', N'Item1', CAST(N'2019-11-14T14:34:00.000' AS DateTime), 38)
INSERT [dbo].[Test] ([ID], [Product], [datetime], [Cumulative_Packed]) VALUES (N'21        ', N'Item1', CAST(N'2019-11-14T14:35:00.000' AS DateTime), 38)

【问题讨论】:

  • 不确定您如何定义结束时间。
  • 同时给出create table和insert data语句。
  • 使用创建表和插入代码更新帖子。谢谢
  • 结束时间在下一个项目之前的最后一条记录上定义。但是累积增加的地方。所以在我给出的例子中。对于产品运行 1,我预计结束时间为 14:18,因为累积包装没有增加 14:19 和 14:20。

标签: sql tsql


【解决方案1】:

我认为您希望 lead()lag() 识别开始和停止。对于您的数据:

select row_number() over (order by min(datetime)) as run_order,
       product, min(datetime), max(datetime),
       max(cumulative_packed)
from (select t.*,
             sum(case when prev_cp = 0 or prev_cp is null then 1 else 0 end) over (partition by product order by datetime) as rungrp
      from (select t.*,
                   lag(cumulative_packed) over (partition by product order by datetime) as prev_cp,
                   lead(cumulative_packed) over (partition by product order by datetime) as next_cp
             from t
            ) t
       where (prev_cp = 0 or prev_cp is null) or              -- is start
             (next_cp = cp or next_cp = 0 or next_cp is null) -- is stop
      ) t
group by rungrp, product
order by rungrp, product, min(datetime);

编辑:

您的数据似乎需要重复删除。根据我所遵循的,您只需要 first 值更改的时间。这可以通过一个额外的子查询层来处理:

select row_number() over (order by min(datetime)) as run_order,
       product, min(datetime), max(datetime),
       max(cumulative_packed)
from (select t.*,
             sum(case when prev_cp = 0 or prev_cp is null then 1 else 0 end) over (partition by product order by datetime) as rungrp
      from (select t.*,
                   lag(cumulative_packed) over (partition by product order by datetime) as prev_cp,
                   lead(cumulative_packed) over (partition by product order by datetime) as next_cp
             from (select t.*,
                          lag(cumulative_packed) over (partition by product order by datetime) as first_prev_cp
                   from t
                  ) t
             where first_prev_cp is null or first_prev_cp <> cumulative_packed
            ) t
       where (prev_cp = 0 or prev_cp is null) or              -- is start
             (next_cp = cp or next_cp = 0 or next_cp is null) -- is stop
      ) t
group by rungrp, product
order by rungrp, product, min(datetime);

【讨论】:

  • 谢谢 Gordon - 但还没有。完成时间实际上是最后一个包注册的时间。在我给出的示例中,对于第 1 项的第一次产品运行,我预计完成时间是 14:18,因为实际上在 14:19 或 14:20 没有打包。
  • @danielcharlesworth。 . .我编辑了答案。我认为您只需要第一次将特定的“累积”打包出现在序列中。这应该更适合您的目的。
  • 我认为您在正确的行上,但您的查询无法运行 - 我已经尝试了代码,但我最终得到了最低的累积打包时间,并且开始/结束时间不正确。跨度>
  • @danielcharlesworth。 . .错误的比较。立即尝试。
  • 谢谢 Gordon - 主要负责我的测试数据 - 我将应用于实际。非常感谢
猜你喜欢
  • 1970-01-01
  • 2015-03-13
  • 1970-01-01
  • 2017-12-11
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-22
相关资源
最近更新 更多