2012-05-04 9 views
7

私は、与えられたアーティストの集合が好きなすべてのユーザを選択したいという質問があります。また、その他のWHERE基準などもあります。スキーマの外観は次のとおりです。Postgresql Query - サブクエリの結果による注文

  users      favourite_artists    artists 

+----------+------------+ +-----------+------------+ +--------+--------+ 
| id | country | | user_id | artist_id | | id | name | 
+----------+------------+ +-----------+------------+ +--------+--------+ 
|  1 |  gb  | |  1  |  6  | | 1 | Muse | 
|  2 |  gb  | |  1  |  5  | | 2 | RATM | 
|  3 |  us  | |  1  |  3  | | 3 | ABBA | 
|  4 |  us  | |  2  |  3  | | 4 | U2 | 
+----------+------------+ +-----------+------------+ +--------+--------+ 

好きなアーティストの数で注文したいと思います。また、どのアーティストも好きではなく、WHERE基準に合致するユーザーを含めることもできます。予想される結果セットは次のようになります。

+--------+---------------+----------------+ 
| id | country | match_count | 
+--------+---------------+----------------+ 
| 6 |  gb  |  4  | 
| 9 |  gb  |  4  | 
| 2 |  gb  |  3  | 
| 1 |  gb  |  2  | 
| 5 |  gb  |  0  | 
| 4 |  gb  |  0  | 
+--------+---------------+----------------+ 

私はそれによってmatch_countと順序を取得するには、サブクエリを使用してそれを実行しようとしてきたが、私はより良い方法があることがあるだろうと思ったので、それはかなりゆっくりと行っています。

SELECT users.id, users.country 
    (SELECT COUNT(*) FROM favourite_artists 
    WHERE user_id = users.id AND artist_id IN (1,3,4,9)) AS match_count   
    FROM "users" 
    WHERE users.country = 'gb' 
    ORDER BY match_count DESC; 

私はPostgreSQL 9.0.7を使用しています。何かご意見は?

答えて

6

クエリでは、すべての行に対して1つのサブクエリがusersに実行されています。このようなクエリは、「相関サブクエリ」と呼ばれ、そのパフォーマンスはかなりわかりやすいです。いっそmulti-column indexfavourite_artists(user_id, artist_id)か - あなたはfavourite_artists(user_id)にインデックスを持っていると仮定すると、

SELECT users.id, users.country, count(artist_id) as match_count 
FROM users 
LEFT JOIN favourite_artists ON user_id = users.id AND artist_id IN (1,3,4,9) 
WHERE users.country = 'gb' 
GROUP BY 1, 2 
ORDER BY 3 DESC; 

このクエリは、はるかに効率的に参加する行を取得します:

は、代わりにあなたが参加したいと思います。

+1

+1は素晴らしいイントロです。 :) –

+1

ORDER BY句の位置に依存すると、結果セット内のフィールドの順序が決定されないという関係理論に違反します。私は代わりに "ORDER BY match_count"を提案します。 –

+1

@JoelFinkel何も違反していません。列の順序は*クエリ内で定義されているので、カプセル化はそのままです。大丈夫だよ。私は、何人かの人がなぜこの結果について何か他のことに全く何の違いもない、この信じられないほど些細な問題を抱えてパンチを得る理由を理解できません。揚げる魚がより大きくなります。実際には、揚げる魚*があります - これは魚でもありません。何でもありません。 – Bohemian