2017-12-21 8 views
0

親と子の両方を含むテーブルがあります。私の質問は、その親をつかむSQL文を形成する方法や子供があるされ、両親親と子が両方とも同じテーブルにある子を取得するためにSQLを使用する

Select * from inventory where subID=parentID 

を通じて

Select * FROM inventory WHERE subID=0 // parents 

ループ:今、私はテーブルに別のコールを行うことができますそれに属しています。

//SQL Results would look like this 
Parent 
- Child 
- Child 
Parent 
- Child 
- Child 
- Child 
etc.. 

本当にありがとうございます!

**更新** これが何であるかはわかりましたが、これは私の試みですが、これは結果を返しません。 id = 0は、それが親であることを示します。何が間違っているのですか?私はそれが今で考え出したと思う

;WITH cte AS (
    SELECT DISTINCT id, parent_id, dateOn, capacity, status, instructorID, rowNum = ROW_NUMBER() OVER (ORDER BY id ASC) 
    FROM inventory 
    WHERE parent_id = 0 AND active='True' AND cID=1 

    UNION ALL 

    SELECT a.id, a.parent_id, a.dateOn, a.capacity, a.status, a.instructorID, b.rowNum 
    FROM inventory a 
    JOIN cte b ON a.parent_id = b.id 
    WHERE a.parent_id <> 0 AND active='True' AND cID=1 
) 
    SELECT id, parent_id, dateOn, capacity, status, (SELECT count(aID) FROM appointments WHERE id=cte.id) as totalCount 
    FROM cte 
    ORDER BY rowNum, id 
+2

これは隣接リストと呼ばれます。これは、このようなデータを格納する非常に一般的な方法です。あなたが望むことをするテクニックは、再帰的なcteと呼ばれます。文字通りこのサイトとインターネットの残りの部分でこれを行う方法の数千、数千、数千の例があります。 –

+0

は応答を感謝します。私は周りを見て、私が見つけることができるかを見てみましょう:) – Damien

+0

あなたが検索する単語を知らないときには、時折、自分自身で答えを見つけるのは難しいです。 –

答えて

1

編集:ここでは

WITH children AS (

    SELECT id, parent_id 
    FROM inventory 
    WHERE id = 0 

    UNION ALL 

    SELECT a.id , a.parent_id 
    FROM inventory a 
    JOIN children b ON b.parent_id = a.id 
) 
    SELECT id, parent_id 
    FROM children 

は次のように作業コードが見えるものです。 CTE内のrowNumは、最終選択のレコードをソートするために使用されます。質問から完全なクエリ使用して

;WITH children AS (
    SELECT DISTINCT id, parent_id, rowNum = ROW_NUMBER() OVER (ORDER BY id ASC) 
    FROM inventory 
    WHERE parent_id = 0 

    UNION ALL 

    SELECT a.id , a.parent_id, b.rowNum 
    FROM inventory a 
    JOIN children b ON a.parent_id = b.id 
    WHERE a.parent_id <> 0  
) 
    SELECT id, parent_id 
    FROM children 
    ORDER BY rowNum, id 

第二編集:dateOnにソートするに

を、あなただけのORDER BY節の先頭にそれを追加したいです。そして、あなたはこれで終わる:

;WITH cte AS (
    SELECT DISTINCT id, parent_id, dateOn, capacity, status, instructorID, rowNum = ROW_NUMBER() OVER (ORDER BY id ASC) 
    FROM inventory 
    WHERE parent_id = 0 AND active='True' AND cID=1 

    UNION ALL 

    SELECT a.id, a.parent_id, a.dateOn, a.capacity, a.status, a.instructorID, b.rowNum 
    FROM inventory a 
    JOIN cte b ON a.parent_id = b.id 
    WHERE a.parent_id <> 0 AND active='True' AND cID=1 
) 
    SELECT id, parent_id, dateOn, capacity, status, (SELECT count(aID) FROM appointments WHERE id=cte.id) as totalCount 
    FROM cte 
    ORDER BY dateOn, rowNum, id 

何が起こっているのかを確認するクエリを打破するのをしてみましょう:

CTEの「アンカーは、」これは、のすべてを取得している

SELECT DISTINCT id, parent_id, dateOn, capacity, status, instructorID, rowNum = ROW_NUMBER() OVER (ORDER BY id ASC) 
FROM inventory 
WHERE parent_id = 0 AND active='True' AND cID=1 

です親レコードをinventoryから削除し、最後の選択で並べ替える目的で親とすべての子を関連付けるために使用できるrownumberを追加します。

CTEの再帰部分はcteがアンカークエリで私たちの親レコードへの再帰参照で、クエリのこの部分で

SELECT a.id, a.parent_id, a.dateOn, a.capacity, a.status, a.instructorID, b.rowNum 
FROM inventory a 
JOIN cte b ON a.parent_id = b.id 
WHERE a.parent_id <> 0 AND active='True' AND cID=1 

です。ここでは親レコード以外のレコードを親レコードに結合します。親のrowNumを使用するので、親とその子はすべてこのフィールドに同じ値を持ちます。

最後のselect文は、CTEからすべての行を返します。 dateOnを最初に注文し、同じdateOnを共有するすべての親/子レコードが一緒になるようにします。次に、rowNumで注文し、各親が子どもと一緒になるようにします。最後に、idをソートします。親の子は、子供よりも小さいidの値を持つと仮定します。親がより大きいidを持っているならば、parent_idで代わりに注文することができますので、親レコード(子供の前にparent_id = 0)が現れます。

+0

ええと...私はそれを試みて、最終的にいくつかの結果を得ましたが、それは両親だけを返しました。だから私はparent_id where節を削除して、今はすべての情報を提供していますが、情報はオフになっています...子どもたちを何度も繰り返して子供たちをリストアップしていません:\ – Damien

+0

@Damien、 –

+0

WOW! 2つのこと、私はクエリに必要なものすべてを含めるように私のコードを更新しました。 dateOnで注文する方法また、これはそのdateOn部分の他にかなりうまくいくように思えました。あなたは何をしたのか説明してください。私はこれを学ぶことができます。ダミーのためにそれを壊す – Damien

関連する問題