我设计了一个数据库,其中存储了执行流程所需的所有信息。通过“处理”,我指的是一系列多个步骤,或者换句话说,一个配方。每个配方(在我的情况下是任务)包含几个步骤。给定的步骤可以出现在不同的配方中。
以下是我拥有的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
列是一个布尔值,指定根据任务执行的第一步。
遵循这个逻辑,为了“玩数字游戏”,您需要先打开控制台,然后登录,然后打开游戏,最后享受您的游戏会话。
我的问题是: 我想找到一种方法来查询完成给定任务所需的所有步骤,并按照适当的顺序(根据 Process 表执行它们的顺序)对它们进行排序。有人知道如何做到这一点(如果可能的话,在一个查询中)?
基本上,查询应首先获取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
欢迎任何暗示帮助!
谢谢
编辑:评论中要求的AS,以下是此类查询的预期结果,如果是为了播放数字'任务:
+-----------------+
| StepNane |
+-----------------+
| Turn Console On |
| Log In |
| Open Game |
| Enjoy |
+-----------------+
答案 0 :(得分:2)
使用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
答案 1 :(得分:0)
获取NextID需要LEAD or LAG。
答案 2 :(得分:0)
可以使用DB Cursor和Dynamic query编写。
所以我的想法是,为Process
表打开一个DB Cursor,NextID
为TRUE
。
在Cursor内部,创建一个动态查询:
NextID
=光标NextID
NextID
= 0