“ hasChildren”を実装する方法SQLのSELECTステートメント?
質問
次の表があるとします:
ID | parentID | MoreStuff
1 | -1 | ...
2 | 1 | ...
3 | 1 | ...
4 | 2 | ...
5 | 1 | ...
特定の行に子があるかどうかを確認するSQL SELECTステートメントを生成するにはどうすればよいですか?つまり、ID 1に子があり、この場合は3であるかどうかを知りたいです。
SQLステートメントの作成方法がわからない:
SELECT ID, hasChildren FROM myTable;
上記のSQL SELECTステートメントでhasChildrenに置き換えられるものは何ですか?
解決
グループバージョンなし:
SELECT MyTable.Id, CASE WHEN EXISTS
(SELECT TOP 1 1 --you can actually select anything you want here
FROM MyTable MyTableCheck
WHERE MyTableCheck.ParentId = MyTable.Id
) THEN 1 ELSE 0 END AS HasRows
FROM MyTable
他のヒント
テーブルに参加して、子があるかどうかを確認します。
SELECT
parent.id as ID
, case when count(child.id) > 0 then 1 else 0 end as hasChildren
FROM myTable parent
LEFT JOIN myTable child
ON child.parentID = parent.ID
GROUP BY parent.id
既に親IDがわかっている場合、クエリは簡単です。親IDの行数を選択するだけです。
SELECT count(*) FROM myTable where parentID = 1;
質問に対する非常に有効な回答があります。ただし、データセットが非常に大きい場合は、このようなクエリのパフォーマンスを検討します。
Group ByまたはSub Queryを使用してデータを取得する場合、ID列とParent列の両方に別々のインデックスがあることを確認してください。
パフォーマンスをさらに向上させるには、「haschildren」という列を追加する必要があります。 「ビット」である可能性がありますデータ・タイプ。この列は、アイテムが挿入または削除されたときにアプリケーションコードから更新する必要があります。これにより、より高速なクエリを実行できます。
SELECT * FROM table WHERE haschildren IS NOT NULL
上記の解決策は問題ありませんが、実際にパフォーマンスの問題がある場合を除き、「haschildren」のような列を追加しないでください(GateKillerの投稿を参照)。このような列はデータベースを非正規化します。つまり、同じ情報が2か所に保存されるため、データが矛盾する可能性が高くなります。新しい子を挿入するか、既存の子を削除するか、子の親を更新するたびに、この列を維持する必要があります。