2017-06-13 8 views
0

私はプロセスを実行するために必要なすべての情報を格納するデータベースを設計しました。 「プロセス」とは、複数のステップの連続、つまりレシピを意味します。各レシピ(私の場合のタスク)にはいくつかのステップがあります。与えられたステップは異なるレシピで表示されます。ここ前の行の値に応じてSQLクエリを注文します

私は(ランダムデータで)を有する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  | 
+----+--------------+-----------------+--------+-----------+ 

、各レコード(行)タスクおよびステップの組み合わせを表す。なお、この表で理解するのが容易であってもよいです。 NextID列には、レシピに従うときに、次のタスク - ステップの組み合わせのIDが含まれます。 NextID0の場合、タスクが終了します。 StartHere列は、タスクに応じて実行される最初のステップを指定するブール値です。

「デジタルゲームをプレイする」ためには、コンソールの電源を入れ、ログインしてゲームを開き、最後にゲームセッションを楽しんでから始める必要があります。

私の質問です:私は、適切な順序(彼らはプロセステーブルに従って実行する順序)に与えられたタスクと順番にそれらを完了するために必要なすべての手順を照会するための方法を見つけたい 。可能であれば、どのようにこれを(1つのクエリで)行うことができるか、誰かが考えていますか?

基本的には、クエリが最初にIDそうに前の行のNextIDとを等しく有する行のStepNameを取得し、StartHereTRUEある行のStepNameを取得する必要があります。

私は次のクエリを思い付いたが、コースを外れ、これは私に正しい順序与えるものではありません:

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 

のヒントのすべてのヘルプは大歓迎です!

はあなたに

EDITありがとう:コメントで要求されるように、ここではそれがために行われた場合、このようなクエリの予想結果であるタスク「デジタル再生」:

+-----------------+ 
| StepNane  | 
+-----------------+ 
| Turn Console On | 
| Log In   | 
| Open Game  | 
| Enjoy   | 
+-----------------+ 
+0

から開始 – maSTAShuFu

+0

@maSTAShuFuが命題ありがとうござい期待される結果を投稿してください。私は、期待される結果を投稿に加えました。 –

+0

バージョンのSQL Server? – maSTAShuFu

答えて

2

動的なクエリを実行し

  • NextID = 0になるまで...

    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

    から開始します

    結果、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 
    
    +0

    ありがとうございます! CTEについて聞いたことはありませんが、あなたの記事の後に、私は行って少し研究を行い、彼らがどれほど有用であるか信じられませんでした!あなたができることの全く新しい範囲を開きます!皆さんはCommon Table Expressionsについて学ぶべきだと思っています... –

    +0

    CTEクエリ定義の最初のSELECT文は、再帰が完了した後も常に同じ結果が得られるように1行しか返さないようにしてください。そのため、 'StartHere'ブール列の代わりに' WHERE'節に 'ID'でフィルタリングするのはなぜですか? –

    +0

    これはあなたの親クエリまたはベースクエリです – maSTAShuFu

    0

    LEAD or LAGのような音をNextIDを取得するために必要です。

    0

    DBカーソルと動的クエリを使用して記述できます。

    考え方は、ProcessテーブルのDBカーソルを開きます。NextIDTRUEです。カーソルインサイド

    、動的なクエリを作成します。カーソル変数から

    1. まず値を選択。
    2. 連合 - 値を選択NextID =カーソルNextID
    3. 繰り返し2次のIDの形式で子ノード原理を取得し、CTEを使用して
    +0

    アイデアありがとう。それは私が必要としているようです。あなたは例を挙げていただけますか? –

    +0

    まず第一に、カーソルを使用しないで、解決策はCTEです。子が次の番号であるすべての子を取得します。 – maSTAShuFu

    +0

    私は同意する、カーソルは使用する賢明なオプションではありません。これにはCTEが適しています。 – Nabid

    関連する問題