2

テーブルが 2 つあります。ユーザーと意見。以下のサンプル スキーマとデータ

users table
---------------------------------
userid
  1
  2
  3
  4
  5

opinions table
---------------------------------
opinionid   |   points   |   yes   |   no
    1             5         1,2,3      4,5
    2             5         1,3,5      2,4
    3            10         1,2,4      3,5
    4            10         1,4,5      2,3
    5            15           1      2,3,4,5

* the yes and no columns contains comma-delimited userids

望ましい結果: ユーザー ID によるグループ化、点数による並べ替え、はい、いいえ

userid   |   points   |   yes   |   no
  1            45          5         0
  4            20          2         3
  2            15          2         3
  5            15          2         3
  3            10          2         3

Summary: for each userid, sum(points), count(yes), count(no)

ありがとう!

4

3 に答える 3

2

値をカンマ区切りで保存するのではなく、データを正規化する必要があります。これにより、クエリでの処理が容易になります。新しい列user_idを外部キーとして追加し、列をフラグとして追加するだけYesOrNoで、意見ごとにユーザーIDを入力し、フラグ値0または1を設定します。


今のところ、このFIND_IN_SET関数を使用して、次のように探していることを実行できます。

SELECT
  userid,
  sum(CASE WHEN type = 'yes' THEN points ELSE 0 END), 
  SUM(CASE WHEN type = 'yes' THEN 1 ELSE 0 END) AS Yes,
  SUM(CASE WHEN type = 'no' THEN 1 ELSE 0 END) AS No
FROM
(
  SELECT 
    o.opinionid,
    o.points,
    'yes' AS type,
    u.userid
  FROM options AS o
  INNER JOIN users AS u ON FIND_IN_SET(u.userid, o.yes) <> 0
  UNION
  SELECT
    o.opinionid,
    o.points,
    'no' AS type,
    u.userid
  FROM options AS o
  INNER JOIN users AS u ON FIND_IN_SET(u.userid, o.no) <> 0
) AS t
GROUP BY userid;
于 2013-09-30T11:48:55.187 に答える
0

これがシンプルでエレガントなソリューションです

    select userid, 
    sum(if(FIND_IN_SET(userid, yes.yes)>0, yes.points, null)) as points, 
    count(if(FIND_IN_SET(userid, yes.yes)>0,1,null)) as yes, 
    count(if(FIND_IN_SET(userid, yes.no)>0,1,null)) as no

        from users 
        left join opinions as yes 
        on (FIND_IN_SET(userid, yes.yes)>0 or FIND_IN_SET(userid, yes.no)>0)
    group by userid
于 2013-09-30T11:52:01.520 に答える