[英]Order SQL Query Depending on Value of Previous Row
我设计了一个数据库,在其中存储执行过程所需的所有信息。 “过程”是指多个步骤的连续性,换句话说,就是一个配方。 每个配方(在我的案例中为Task)包含几个步骤。 给定的步骤可以出现在不同的配方中。
这是我拥有的3个表(带有随机数据)的示例:
工艺表
+----+------+------+--------+-----------+
| ID | Task | Step | NextID | StartHere |
+----+------+------+--------+-----------+
| 1 | 2 | 1 | 4 | TRUE |
| 2 | 2 | 5 | 8 | FALSE |
| 3 | 4 | 5 | 9 | FALSE |
| 4 | 2 | 2 | 2 | FALSE |
| 5 | 4 | 2 | 6 | FALSE |
| 6 | 4 | 4 | 3 | FALSE |
| 7 | 4 | 1 | 5 | TRUE |
| 8 | 2 | 15 | 0 | FALSE |
| 9 | 4 | 15 | 0 | FALSE |
+----+------+------+--------+-----------+
任务表
+--------+--------------+
| TaskID | TaskName |
+--------+--------------+
| 1 | Buy Disk |
| 2 | Play Disk |
| 3 | Buy Digital |
| 4 | Play Digital |
+--------+--------------+
步骤稳定
+--------+-----------------+
| StepID | StepName |
+--------+-----------------+
| 1 | Turn Console On |
| 2 | Log In |
| 4 | Insert Disk |
| 5 | Open Game |
| 15 | Enjoy |
+--------+-----------------+
这是上面的“ 过程”表,但带有“步骤和任务”的实际名称。 该表可能更易于理解:
+----+--------------+-----------------+--------+-----------+
| ID | Task | Step | NextID | StartHere |
+----+--------------+-----------------+--------+-----------+
| 1 | Play Disk | Turn Console On | 4 | TRUE |
| 2 | Play Disk | Open Game | 8 | FALSE |
| 3 | Play Digital | Open Game | 9 | FALSE |
| 4 | Play Disk | Log In | 2 | FALSE |
| 5 | Play Digital | Log In | 6 | FALSE |
| 6 | Play Digital | Insert Disk | 3 | FALSE |
| 7 | Play Digital | Turn Console On | 5 | TRUE |
| 8 | Play Disk | Enjoy | 0 | FALSE |
| 9 | Play Digital | Enjoy | 0 | FALSE |
+----+--------------+-----------------+--------+-----------+
如图所示,在Process表中,每个记录(行)代表Task和step的组合。 遵循配方时, NextID
列包含“下一步任务-步骤”组合的ID。 NextID
为0
表示任务已结束。 StartHere
列是一个布尔值,它根据任务指定要执行的第一步。
按照这种逻辑,为了“玩数字游戏”,您需要首先打开控制台,然后登录,然后打开游戏,最后享受游戏时光。
我的问题是:我想找到一种方法来查询完成给定任务所需的所有步骤,并按照适当的顺序(应根据“ 流程”表执行这些步骤的顺序)对其进行排序。 是否有人知道如何做到这一点(如果可能,在一个查询中)?
基本上,查询应先拿到StepName
其中行的StartHere
为TRUE
,然后拿到StepName
有一个行的ID
等于NextID
前一行等。
我提出了以下查询,但是当然这不能给我正确的顺序:
SELECT Step.StepName
FROM Step
INNER JOIN Process ON Step.StepID = Process.Step
INNER JOIN Task ON Process.Task = Task.TaskID
WHERE Task.TaskID = 4
ORDER BY Process.NextID
欢迎任何提示的帮助!
谢谢
编辑 :按注释中的要求,如果已针对“播放数字”任务完成,则这是该查询的预期结果:
+-----------------+
| StepNane |
+-----------------+
| Turn Console On |
| Log In |
| Open Game |
| Enjoy |
+-----------------+
使用CTE,以Next id的形式获取子节点原理。
declare @mytable table
(id int,
task varchar(50),
step varchar(50),
nextid int
)
insert into @mytable
values
( 1 ,'Play Disk ','Turn Console On ', 4 ),
( 2 ,'Play Disk ','Open Game ', 8 ),
( 3 ,'Play Digital ','Open Game ', 9 ),
( 4 ,'Play Disk ','Log In ', 2 ),
( 5 ,'Play Digital ','Log In ', 6 ),
( 6 ,'Play Digital ','Insert Disk ', 3 ),
( 7 ,'Play Digital ','Turn Console On ', 5 ),
( 8 ,'Play Disk ','Enjoy ', 0 ),
( 9 ,'Play Digital ','Enjoy ', 0 )
;with mycte
as
(
select * from @mytable where id = 1 -- to start from this ID, if you want this your START here column with true then eventually you will have multiple outputs
union all
select t.* from @mytable t
inner join mycte c on c.nextid = t.id
)
select * from mycte;
结果,从1开始
id task step nextid
1 Play Disk Turn Console On 4
4 Play Disk Log In 2
2 Play Disk Open Game 8
8 Play Disk Enjoy 0
结果,从7开始
id task step nextid
7 Play Digital Turn Console On 5
5 Play Digital Log In 6
6 Play Digital Insert Disk 3
3 Play Digital Open Game 9
9 Play Digital Enjoy 0
听起来需要LEAD或LAG才能获取NextID。
可以使用DB Cursor和Dynamic查询编写。
因此,想法是打开NextID
为TRUE
用于Process
的DB游标。
在游标内,创建一个动态查询:
NextID
=游标NextID
值 NextID
= 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.