小编典典

TSQL检查特定的行序列是否存在

sql

我有一个包含字段的表:

History_ID   ORDER_ID   Previous_STATUS_ID   Next_STATUS_ID
0            2          null                 1
1            2          1                    2
2            2          2                    3
3            1          null                 1
4            2          3                    4
5            3          null                 2
6            2          4                    1
7            2          1                    2
8            2          2                    5
9            7          3                    4

10 4 6 2 11 9 3 5

它包含我的订单IDID状态。基本上,表格包含STATUS每个订单的历史记录。

我想检查一个特定的订单是否具有特定的订单顺序。

示例:如果订单ID 4具有状态,2,4,3,1则返回true

状态应为一个接一个,因此2之后必须为4,4之后为3以及之后为1。

这些顺序为我提供了有关特定订单流程的信息(将在我的报告中显示)。

我需要检查这种序列:

  • 1,2,3
  • 1,4,3,2
  • 4,2
  • (1或2或3或4),5,3-这4个中的一个,然后是5个,然后是3个

我不知道如何从这种查询开始:/

编辑:
我的最终报告是一个表,其中包含有关订单的信息,如下所示:

Orders type  Count      ...
Profile1     145        ...
Profile2     217        ...
Profile3     12         ...
Profile4     2          ...

我大约有80万多个订单,我的报告必须每天完成,因此,我决定创建整个表(检查那些状态并汇总其他表中的信息),而我决定创建一个报告表:

Order_ID   Profile   Order_date   Customer_profile     ...
1          5        '2008-01-03'  2
4          1        '2009-04-10'  3
3          7        '2011-11-03'  1
4523       2        '2012-11-03'  5

这样我就可以创建一个夜间工作,该工作将使用我的信息向该表添加新订单,并且我将仅从该表中进行简单选择,以避免聚合。第一次插入将很大,但是在第二天晚上,它将仅添加新订单。

例如,查看ID = 2
Next_STATUS_ID ale的订单,如下所示:1,2,3,4,1,2,5
…我想检查此订单是否具有历史更改,例如1,2,5,所以我的函数(select语句)如果按顺序找到那些ID,则应重复1。


阅读 174

收藏
2021-04-07

共1个答案

小编典典

我认为可以使用递归CTE解决此问题:

with change_tree as 
(
  SELECT order_id,
         previous_status_id, 
         next_status_id,
         cast(next_status_id as varchar(max)) as status_path
  FROM status_change
  WHERE previous_status_id = 1
    AND order_id = 2

  UNION ALL

  SELECT sc.order_id,
         sc.previous_status_id,
         sc.next_status_id,
         ct.status_path + ',' + cast(sc.next_status_id as varchar(max))
  FROM status_change sc 
    JOIN change_tree ct ON ct.next_status_id = sc.previous_status_id AND ct.order_id = sc.order_id
)
SELECT *
FROM change_tree
WHERE status_path = '2,3,5';

这实际上是(递归地)将next_status_id的所有值连接到一个您可以比较的字符串中。

从您的样本数据中,我还不清楚哪条行标记着订单状态更改历史记录的“开始”。您将需要调整并集的第一部分中的位置,以选择正确的“开始”行。

2021-04-07