event
から単一のteam
を取得するための、最も簡単で効率的なSQLクエリを作成します。しかしevent
はteam
とは直接関係していない可能性があり、テーブル関係階層のどのレベルでも関連している可能性があります。SQLで任意の子関係の "親"を照会する方法は?
注意するカップルの事を:
セットアップ
は、ここに私のスキーマがどのように見えるかの単純化した表現だ
teams
は多くのcollections
を持つことができ、apps
、webhooks
。collections
もまた、多くのwebhooks
を持つことができます。webhooks
は、team
またはcollection
のいずれかに属することができますが、1つのみです。events
は、任意のオブジェクトに属することができますが、1つだけです。
これは、ほとんどのSaaS型企業(例えば、スラックまたはストライプ)が持つようなかなり基本的な設定のようです。すべてが「チーム」の下にグループ化され、ユーザーはメンバーとしてメンバーと交流することができます。
問題セットアップ、私は解決SQLクエリを作成したいことを考えると...
は
id
によってイベントのチームを検索します。
親チームを直接または特定の方法で間接的に検索するクエリを簡単に作成できます。たとえば...
は直接「チームイベント」に関連のチームを検索します。
SELECT teams.*
FROM teams
JOIN events ON events.team_id = teams.id
WHERE events.id = ${id}
それとも...
間接的関連の "コレクションイベント" のチームを検索します。
SELECT teams.*
FROM teams
JOIN collections ON collections.team_id = teams.id
JOIN events ON events.collection_id = collections.id
WHERE events.id = ${id}
彼らは2つの異なる方法で関連することができますので、ウェブフックは、より複雑な取得...
は、「ウェブフックイベント」関連間接的のチームを検索します。
SELECT teams.*
FROM teams
JOIN collections ON collections.team_id = teams.id
JOIN webhooks AS team_webhooks ON team_webhooks.team_id = teams.id
JOIN webhooks AS collection_webhooks ON collection_webhooks.collection_id = collections.id
JOIN events AS team_webhook_events ON team_webhook_events.webhook_id = team_webhooks.id
JOIN events AS collection_webhook_events ON collection_webhook_events.webhook_id = collection_webhooks.id
WHERE team_webhook_events.id = ${id}
OR collection_webhook_events.id = ${id}
私は、パフォーマンスのために優れているか不明私はそのように書くべきであるかどうかわからないんだけど、またはその代わりにUNION
を使用して...
SELECT teams.*
FROM teams
JOIN webhooks ON webhooks.team_id = teams.id
JOIN events ON events.webhook_id = webhooks.id
WHERE events.id = ${id}
UNION
SELECT teams.*
FROM teams
JOIN collections ON collections.team_id = teams.id
JOIN webhooks ON webhooks.collection_id = collections.id
JOIN events ON events.webhook_id = webhooks.id
WHERE events.id = ${id}
...。
ご覧のとおり、特定のチームに1つのイベントを関連付けるには、これらのすべてのパスを使用する方法がたくさんあります。私は「すべての包括的な」クエリを記述しようとするので、それはそれをUNION
道をやってスーパー複雑な...
潜在的な解決策#1
なってしまう、私はちょうどクエリの束を作ることができると思います、そしてそれを一緒に組み合わせると、これは無駄かもしれないようですが?
SELECT teams.*
FROM teams
JOIN events ON events.team_id = teams.id
WHERE events.id = ${id}
UNION
SELECT teams.*
FROM teams
JOIN apps ON apps.team_id = teams.id
JOIN events ON events.app_id = apps.id
WHERE events.id = ${id}
UNION
SELECT teams.*
FROM teams
JOIN collections ON collections.team_id = teams.id
JOIN events ON events.collection_id = collections.id
WHERE events.id = ${id}
UNION
SELECT teams.*
FROM teams
JOIN webhooks ON webhooks.team_id = teams.id
JOIN events ON events.webhook_id = webhooks.id
WHERE events.id = ${id}
UNION
SELECT teams.*
FROM teams
JOIN collections ON collections.team_id = teams.id
JOIN webhooks ON webhooks.collection_id = collections.id
JOIN events ON events.webhook_id = webhooks.id
WHERE events.id = ${id}
潜在的な解決策#2
使用して、複数のJOIN
sが私がteams
との関係で、一緒にイベントの所有者の異なる組み合わせの全てに参加することができるかもしれないと思いますか?これはまた、JOIN
の多くのように思えるが...
SELECT teams.*
FROM teams
JOIN apps ON apps.team_id = teams.id
JOIN collections ON collections.team_id = teams.id
JOIN webhooks AS team_webhooks ON team_webhooks.team_id = teams.id
JOIN webhooks AS collection_webhooks ON collection_webhooks.collection_id = collections.id
JOIN events AS app_events ON app_events.app_id = apps.id
JOIN events AS collection_events ON collection_events.collection_id = collections.id
JOIN events AS team_events ON team_events.team_id = teams.id
JOIN events AS collection_webhook_events ON collection_webhook_events.webhook_id = collection_webhooks.id
JOIN events AS team_webhook_events ON team_webhook_events.webhook_id = team_webhooks.id
WHERE app_events.id = ${id}
OR collection_events.id = ${id}
OR team_events.id = ${id}
OR collection_webhook_events.id = ${id}
OR team_webhook_events.id = ${id}
質問
- は、これらの潜在的な解決策のいずれかは、それを行うための最善の方法はありますか?
- もっと効率的な書き方がありますか?
- 後で読むのが簡単で、読みやすい方法がありますか?
編集:私はこの質問が重複しているとは思いません!
昨日、私は"How to query for nested relationships in SQL?"に似たデータ構造(同じものなので)を尋ねました。同様の方法で書かれました。しかし、私が知る限り、その質問は実際には逆です。最初に
、私はどのように求めていた...
はIDによって指定されたユーザーに(直接または間接的に)関連するイベントのすべてを検索します。あるいは、より親しんだIDがあれば、木のようなデータモデルで可能なすべての子孫を見つけます。
しかし、このいずれかで、私は...
は、IDによって、任意のイベントのチームを検索する方法を求めている
。より一般的に言えば、階層の任意のレベルで木のようなデータモデルに接続できる任意の "子" IDがあれば、その一致する親を見つけることができます。 (それは本質的に最初の質問の逆です。)
そして私が知る限り、それらはさまざまな解決策を含んでいます。最初は、ツリーをたどってすべてのイベントを収集する際に、一連のクエリを実行する必要があります。 2番目の方法は、私はあまり確かではありませんが、結合されたモデルをすべて構築し、そのうちのどれが特定のイベントに一致するかを確認する必要があるようです。
私はそれを重複ではないとマークするのを手伝ってください!
ダブル編集:いいえ、重複してマークされていません!ありがとう:D
この質問はhttp://stackoverflow.com/questions/43267473/how-to-simply-and-efficiently-query-for-nested-relationships-in-からそれほど異なっていないようですSQL。 –
ここにはUNIONがあります。 –
あるいは、テーブルに常に 'team_id'値を含めるようにスキーマを設計し直すことができます(そして、' MATCH SIMPLE'でマルチカラムの外部キーを使うことができます。この方法では、特定のチームに関連しているオブジェクトを見つけるために高度なクエリを書く必要はありません。 – pozs