多くのテーブルと左結合を含む MySQL の状況があり、問題を解決できません。
私はそれを段階的に単純化しようとします。
私がしようとしている主なタスクは、2 つのテーブルを結合することです。最初のテーブルにはアイテムが含まれ、2 番目のテーブルにはアイテムに対して実行されるアクションが含まれます。items テーブルのすべての行を出力する必要があるため (アクションが実行されていない場合でも)、左結合が解決策のようです:
select item.ID, count(action.ID) as cnt
from item
left join action on action.itemID=item.ID
group by ID
次のステップは、実際に特定の種類のアイテムだけを数える必要があるということです。他の型は必要ないので、where 句でそれらを除外します。
select item.ID, count(action.ID) as cnt
from item
left join action on action.itemID=item.ID
where item.type=3
group by ID
ここで、事態はもう少し複雑になります。また、別のテーブル (info) を使用して一部の項目を除外する必要があります。そこでは、どうすればいいのかわかりませんでした。しかし、単純な結合と where 句でそれができました。
select item.ID, count(action.ID) as cnt
from (item, info)
left join action on action.itemID=item.ID
where item.type=3 and info.itemID=itemID and info.fr is not null
group by ID
ここまでは順調ですね。私のクエリは機能し、パフォーマンスは期待どおりです。ここで、最後に行う必要があるのは、別のテーブル (サブアクション) に基づいていくつかのアクション (カウントしない) を除外することです。これは、物事が本当に遅くなり、私を混乱させる場所です. 私はこれを試しました:
select item.ID, count(action.ID) as cnt
from (item, info)
left join (
action join subaction on subaction.actionID=action.ID and subaction.type=6
) on action.itemID=item.ID
where item.type=3 and info.itemID=itemID and info.fr is not null
group by ID
この時点で、クエリは突然 1000 倍以上遅くなります。私は明らかに何か間違ったことをしています!
必要なことをほぼ実行する単純なクエリを試しました。唯一の問題は、一致するアクションが必要なアイテムが含まれていないことです。しかし、私もそれらが必要です。
select item.ID, count(action.ID) as cnt
from item, info, action, subaction
where item.type=3 and info.itemID=itemID and info.fr is not null and
action.itemID=item.ID subaction.actionID=action.ID and subaction.type=6
group by ID
このような問題を解決する方法について誰か提案がありますか? それを行う標準的な方法はありますか?どうもありがとう !
編集
実際、私が提出した最後のクエリは、私が必要としているもののほとんどです。サブクエリが含まれておらず、非常にパフォーマンスが高く、インデックスを最適に使用し、読みやすいなどです。
select item.ID, count(action.ID) as cnt
from item, info, action, subaction
where item.type=3 and info.itemID=itemID and info.fr is not null and
action.itemID=item.ID subaction.actionID=action.ID and subaction.type=6
group by ID
機能しない唯一の小さなことは、count(action.ID) が 0 の場合に item.ID が含まれないことです。
したがって、私の質問は、count(action.ID) が 0 のときに item.IDs も返すように、上記のクエリを少し変更する方法だと思います。それらの余分な item.IDs をカウントとして 0 で含めるだけです。