1

@Bill Karwinによるこの優れた回答をしばらく前に読みました。

https://stackoverflow.com/a/1313293/317889

これはほとんど質問に答えますが、最近クエリを更新して、結合されたテーブルのステータスをフィルタリングする必要がありました。

上記の投稿のクエリと同様に、以下に 2 つのクエリを書きました。遅いクエリである最初のクエリは、結合されたテーブルのステータス フィルタリングで動作します。

SELECT m.*, t1.* FROM mood m 
LEFT JOIN temper t ON ( m._id = t.mood_id ) 
WHERE grantee_username = "username" 
AND m.status_id != 1 // NOT INTERESTED IN THIS FILTER
AND t.status_id != 1 // FILTERING 
GROUP BY m._id;

2 番目のクエリでは、フィルタリングを追加して上記のように機能させる方法がわかりません。

SELECT m.*, t1.* FROM mood m 
LEFT JOIN temper t1 ON ( m._id = t1.mood_id ) 
LEFT JOIN temper t2 ON ( t1.mood_id = t2.mood_id AND t1._id < t2._id ) 
WHERE t2._id IS NULL 
AND m.grantee_username = "username" 
AND m.status_id != 1; // NOT INTERESTED IN THIS FILTER

最初のクエリは完全に機能しますが、2 番目のクエリよりも遅いと見なされます。

2 番目のクエリは、すべてのムード レコードを関連するラスト テンパー レコードに戻すときに機能しますが、ラスト テンパー レコードのステータスが 1 になっている可能性がありますが、これは望ましくありません。

どんな洞察も興味深いでしょう。t.status_idいつでも最初のクエリを使用できますが、パフォーマンスのために、可能であれば 2 番目のクエリにフィルタリングを追加する方法を見つけたいと思います。

4

2 に答える 2

1

わかりました。結局のところ、それほど難しくはありませんでした。

SELECT m.*, t1.* FROM mood m 
LEFT JOIN temper t1 ON ( m._id = t1.mood_id AND t1.status_id !=1) 
LEFT JOIN temper t2 ON ( t1.mood_id = t2.mood_id AND t1._id < t2._id AND t2.status_id !=1 ) 
WHERE t2._id IS NULL 
AND m.grantee_username = "username" 
AND m.status_id != 1; // NOT INTERESTED IN THIS FILTER

フィルター (status_id) を各 JOIN に追加する必要があります。

于 2012-08-25T17:29:44.260 に答える
1

2 番目のクエリの末尾に GROUP BY がないと思います。

このバージョンでは、サブクエリにフィルターが追加されています。

SELECT m.*, t1.*
FROM mood m  LEFT JOIN
     (select t.*
      from temper t
      where t.status_id != 1
     ) t1
     ON m._id = t1.mood_id  LEFT JOIN
     temper t2
     ON t1.mood_id = t2.mood_id AND t1._id < t2._id
WHERE t2._id IS NULL AND
      m.grantee_username = "username" 
GROUP BY m._id;

t2 にもフィルターが必要ですか?

ところで、非表示の列と呼ばれる MySQl の機能を使用しています。1 つの列で集計していますが、他の列では集計関数を使用せずに行を返しています。この機能は MySQL のみです。

于 2012-08-23T15:08:00.840 に答える