繁体   English   中英

根据上一行的值对SQL查询进行排序

[英]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。 NextID0表示任务已结束。 StartHere列是一个布尔值,它根据任务指定要执行的第一步。

按照这种逻辑,为了“玩数字游戏”,您需要首先打开控制台,然后登录,然后打开游戏,最后享受游戏时光。

我的问题是:我想找到一种方法来查询完成给定任务所需的所有步骤,并按照适当的顺序(应根据“ 流程”表执行这些步骤的顺序)对其进行排序。 是否有人知道如何做到这一点(如果可能,在一个查询中)?

基本上,查询应先拿到StepName其中行的StartHereTRUE ,然后拿到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查询编写。

因此,想法是打开NextIDTRUE用于Process的DB游标。

在游标内,创建一个动态查询:

  1. 首先从游标变量中选择值。
  2. 与-结合-选择NextID =游标NextID
  3. 重复2,直到NextID = 0
  4. 执行动态查询

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM