【问题标题】:How do I iterate through subsets of a table in SQL如何在 SQL 中遍历表的子集
【发布时间】:2023-03-03 16:40:04
【问题描述】:

我是 SQL 新手,如果有任何建议,我将不胜感激!

我有一个存储订单历史记录的表。它包括以下列:ORDERIDORDERMILESTONENOTESTIMESTAMP

ORDERID 中的每个 ORDERMILESTONE 对应一个 TIMESTAMP,反之亦然。

我想要做的是比较某些ORDERMILESTONEs 的TIMESTAMPs,以获得从开始到完成或从订单到发货等所需的时间。

为了得到这个,我必须收集特定ORDERID 的所有行,然后以某种方式遍历它们...虽然我试图通过为每个ORDERID 声明一个TVP 来做到这一点,但是这将需要更多时间,因为我的一些数据集长约 20000 行。

你有什么推荐的?提前致谢。

编辑:

在我的问题中,我想找出订单在 QA 中花费的天数。例如,一旦下订单,我们需要制作请求的项目,然后将其发送给 QA。所以有一个里程碑“处理”和一个里程碑“质量保证”。该项目可能在“处理”然后“质量检查”一次,然后被运出,或者它可以被送回质量检查几次,或者在“处理”和“工程”之间来回。我想找出该项目在 QA 中花费的总时间。

以下是一些示例数据:

订单号 |订单里程碑 |注释 |时间戳
43 |放置 |新订购的定制时光机| 07-11-2020 12:00:00
43 |加工 |第一次组装| 07-11-2020 13:00:05
43 |质量保证 |发送给 QA | 07-11-2020 13:30:12
43 |工程 |工程正在修复时间机器上的曲柄,甚至可以跳过数年| 07-12-2020 13:00:02
43 |质量保证 |发送给 QA 以测试新曲柄。时间机器不应该再跳过甚至几年。 | 07-13-2020 16:00:18

0332AT |放置 |用彩虹色定制的光剑| 高分辨率照片| CLIPARTO 07-06-2020 01:00:09
0332AT |加工|光剑正在建造| 高分辨率照片| CLIPARTO 07-06-2020 06:00:09
0332AT |质量保证 |正在测试的光剑| 高分辨率照片| CLIPARTO 07-06-2020 06:00:09

我想要每个订单在 QA 上花费的总天数。

所以我想我可以创建一个查找表,其中包含每个 QA 里程碑及其下一个里程碑。然后总结每个 QA 里程碑与后续里程碑之间的差异。我的主要问题是我不一定知道每个订单需要将商品发送给 QA 多少次...

【问题讨论】:

  • 请提供样本数据、所需结果和适当的数据库标签。
  • 样本数据会很好。什么是主键,我猜是 (ORDERID, ORDERMILESTONE),所以每个订单都有一个里程碑。
  • 每个 ORDERID 可以有多个同名的 MILESTONE,只是时间戳不同。我会拿出一些样本数据。我改变了我实际上正在处理的问题,这样我就不会意外泄露我正在工作的公司的任何专有信息,如果这有意义的话。感谢您的帮助!
  • @GordonLinoff 我想我提供了样本数据和期望的结果。我不确定要包含什么数据库标签。

标签: sql sql-server iteration subset table-valued-parameters


【解决方案1】:

要获得完成所有订单的特定里程碑的时间

select orderid, 
       DATEDIFF(hh, min(TIMESTAMP), max(TIMESTAMP))
from your_table
where ORDERMILESTONE = 'mile stone name'
group by orderid

【讨论】:

    【解决方案2】:

    假设您使用的是 SQL Server,并且您的里程碑没有重复,那么您可以使用:

    select om.orderid, 
           datediff(seconds, min(timestamp), max(timestamp))
    from order_milestones om
    where milestone in ('milestone1', 'milestone2')
    group by om.orderid;
    

    如果您想在每一行上更一般地执行此操作,您可以使用累积聚合函数:

    select om.*, 
           datediff(seconds,
                    timestamp, 
                    min(case when milestone = 'order' then timestamp end) over 
                        (partition by orderid
                         order by timestamp
                         rows between current row and unbounded following
                        )
                   ) as time_to_order
    from order_milestones om
    group by om.orderid;
    

    【讨论】:

      【解决方案3】:

      您可以创建一个查找表,其中包含一个里程碑并为您提供上一个里程碑。然后您可以对其进行左连接并将左连接返回原始表以获取上一个里程碑的相同订单的行并比较日期(sqlfiddle):

      select om.*, datediff(minute, pm.TIMESTAMP, om.TIMESTAMP) as [Minutes]
      from OrderMilestones om
      left join MilestoneSequence ms on ms.ORDERMILESTONE = om.ORDERMILESTONE
      left join OrderMilestones pm on pm.ORDERID = om.ORDERID
            and pm.ORDERMILESTONE = ms.PREVIOUSMILESTONE
      order by om.TIMESTAMP
      

      【讨论】:

      • 感谢杰森的推荐!在我的问题中,我想找到订单在 QA 中花费的天数。例如,一旦下订单,我们需要制作请求的项目,然后将其发送给 QA。所以有一个里程碑“处理”和一个里程碑“质量保证”。该项目可以在“处理”然后“质量检查”一次,然后出去,或者可以多次发送回质量检查。我想找出该项目在 QA 中花费的总时间……这有意义吗?
      • 啊,我看到您在问题中添加了更多数据。查找 row_number()。您可以使用 CTE 和 row_number() over (partition by ORDERID order by TIMESTAMP) as LogId。然后使用b.ORDERID = a.ORDERID and b.LogId = a.LogId + 1 将其链接回自身,因此 a 是您正在查看的日志行,b 是具有更高时间戳的相同订单的 next 行。然后您可以在“a”中获取该行的日期差异。将其放在 CTE 中,您可以按“订单里程碑”分组以查找总持续时间。我认为“里程碑”是一个糟糕的选择,它通常意味着你只能达到一次。
      • 这很有意义。谢谢!!是的,也许“步骤”或“工作区”会比里程碑更好。
      猜你喜欢
      • 2022-01-17
      • 1970-01-01
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      相关资源
      最近更新 更多