6

私は現在、以下のクエリを使用して、カテゴリまたはそのすぐ下のカテゴリで最も多くのポイントを持っている人をリストするポイント システムを使用しています (「category_relations テーブル」の「links_to」と「links_from」を使用)。

SELECT  u.name, 
        pa.user_id, 
        SUM(IF(pa.plus = '1', pa.points_amount, 0)) - 
        SUM(IF(pa.plus = '0', pa.points_amount, 0)) AS points
FROM    points_awarded pa, Users u
WHERE   u.user_id = pa.user_id AND 
        (
           category_id = '" . $category_id . "' OR 
           category_id IN
               (
                   SELECT links_to
                   FROM category_relations
                   WHERE links_from = '" . $category . "'
               )
        ) 
GROUP BY user_id 
ORDER BY points DESC 
LIMIT 50

私が今探しているのは、このクエリを切り替えて、特定のカテゴリのすべてのユーザーを検索するのではなく、特定のユーザーのすべてのカテゴリを検索することです。以下は私が使用しようとしたクエリですが、これにはカテゴリのポイントのみが含まれ、すぐ下のサブカテゴリは含まれません。

SELECT   u.name, 
         pa.user_id, 
         pa.category_id,
         SUM(IF(pa.plus = '1', pa.points_amount, 0)) - 
         SUM(IF(pa.plus = '0',pa.points_amount, 0)) AS points
FROM     points_awarded pa, Users u
WHERE    u.user_id = pa.user_id AND 
         u.user_id = '" . $user_id . "'
GROUP BY pa.category_id 
ORDER BY points DESC 
LIMIT 50
4

2 に答える 2

5

解決

クエリの例から、テーブル構造を単純化して、質問に答えるのに十分な情報を提供することができました。このソリューションを使用できます:

SELECT   a.user_id, 
         a.name, 
         b.category_id,
         SUM(IF(d.plus = '1', d.points_amount, 0)) -
         SUM(IF(d.plus = '0', d.points_amount, 0)) AS points
FROM     Users a
JOIN     points_awarded b ON a.user_id = b.user_id
JOIN     (
         SELECT links_from, links_to 
         FROM   category_relations 
         UNION
         SELECT links_from, links_from
         FROM   category_relations 
         ) c ON b.category_id = c.links_from
JOIN     points_awarded d ON c.links_to = d.category_id
WHERE    a.user_id = $user_id
GROUP BY a.user_id,
         a.name,
         b.category_id
ORDER BY points DESC
LIMIT    50

$user_idクエリのユーザー ID パラメータはどこにありますか。


壊す

基本的に、このクエリの重要な要素は、category_relationsテーブルを選択する方法です。

サブカテゴリ ポイント (各親カテゴリごと)それぞれの親カテゴリのポイントの合計が必要なため、親カテゴリを垂直方向に追加してUNION、基本的にそれ自体をサブカテゴリにすることができます。GROUP BYこれは、 andにうまく考慮されSUMます。

次のような (簡略化された) データがあるとします。

Users
------------------
user_id  |  name
433      |  Zane

points_awarded
------------------
user_id  |  category_id  |  plus  |  points_amount
433      |  1            |  1     |  785
433      |  2            |  1     |  871
433      |  3            |  1     |  236
433      |  4            |  0     |  64
433      |  5            |  0     |  12
433      |  7            |  1     |  897
433      |  8            |  1     |  3
433      |  9            |  0     |  48
433      |  10           |  1     |  124
433      |  14           |  0     |  676

category_relations
------------------
links_from | links_to
1          | 2
1          | 3
1          | 4
5          | 8
5          | 9
7          | 10
7          | 14

親カテゴリとサブカテゴリを区別するために、クエリはpoints_awardedテーブル内の 2 つのフィールドを使用して、テーブルで自己相互参照結合を行いcategory_relationsます。

category_relationsを使用せずにテーブルをそのまま結合した場合UNION、結果の結合は次のようになります (列は簡略化されています)。

points_awarded ⋈ (links_from) category_relations ⋈ (links_to) points_awarded:

category_id  |  points_amount  |  category_id  |  points_amount
1            |  785            |  2            |  871
1            |  785            |  3            |  236
1            |  785            |  4            |  64
5            |  12             |  8            |  3
5            |  12             |  9            |  48
7            |  897            |  10           |  124
7            |  897            |  14           |  676

ご覧のとおり、一番左category_idが親カテゴリで、一番右category_idがそれぞれのサブカテゴリです。最初の category_id とSUM2 番目のpoints_amount...

しかし待ってください。親カテゴリpoints_amountも含める必要があります。どうすれば最初points_amountのものを 2 番目のものに明確に入れることができるpoints_amountでしょうか? ここで のUNION出番です。

自己相互参照結合を実行する前に、category_relationsテーブルをサブ選択して少し変更します。

SELECT links_from, links_to FROM category_relations
UNION
SELECT links_from, links_from FROM category_relations

その結果、次のようになります。

category_relations (subselected)
------------------
links_from | links_to
1          | 1       <-- parent category
1          | 2
1          | 3
1          | 4
5          | 5       <-- parent category
5          | 8
5          | 9
7          | 7       <-- parent category
7          | 10
7          | 14

基本的に、各親カテゴリをそれ自体のサブカテゴリにしました。この結果を結合で使用すると、次が生成されます。

category_id  |  points_amount  |  category_id  |  points_amount
1            |  785            |  1            |  785
1            |  785            |  2            |  871
1            |  785            |  3            |  236
1            |  785            |  4            |  64
5            |  12             |  5            |  12             
5            |  12             |  8            |  3
5            |  12             |  9            |  48
7            |  897            |  7            |  897            
7            |  897            |  10           |  124
7            |  897            |  14           |  676

ここで、カテゴリが に組み込まSUMれ、最初の をグループ化してcategory_id2 番目を合計し(最初のカテゴリは無関係なので、この時点ではpoints_amount無視します)、目的の出力を得ることができます。points_amount

于 2012-08-01T12:03:22.283 に答える
2

category_relationsテーブルに参加することでこれを行う簡単な方法があると確信していますが、テーブルの視覚的な例が表示されないのは難しいです...これはうまくいくはずです:

SELECT   u.name
        ,pa.user_id
        ,pa.category_id,
        SUM(IF(pa.plus = '1', pa.points_amount, 0)) - SUM(IF(pa.plus = '0',pa.points_amount, 0)) AS points
FROM        points_awarded pa
JOIN        Users u
USING       (user_id)
WHERE       category_id IN(
    SELECT      links_to
    FROM        category_relations
    WHERE       links_from = (
        SELECT      category_id
        FROM        points_awarded
        WHERE       user_id = '" . $user_id . "'
    )
)       
GROUP BY    pa.category_id
ORDER BY    points DESC
LIMIT       50

上記の投稿された例では、category_relationsテーブルのレコードが含まれていなかったため、サブカテゴリは表示されませんでした。クエリされたcategory_idによってリンクされたカテゴリを検索する代わりに、サブサブクエリを使用して、ユーザーに関連付けられているすべてのcategory_idを検索します。これを試してみてください。これが正しくない場合は、テーブルデータを示す小さなスニペットを投稿してください。

于 2012-08-01T08:21:30.730 に答える