ユーザー (「投票者」) がさまざまなオブジェクト (場所、Web サイト、回答など、「投票者」) を 1 つから 5 つの星 (「スコア」) で評価する仮説を表すこの表があるとします。この質問のより一般的なバージョンでは、代わりに 1 から N の foo に対して何をすべきかを尋ねます。
mysql> SHOW CREATE TABLE scores;
CREATE TABLE `scores` (
`voter_id` BIGINT NOT NULL DEFAULT '0',
`votee_id` BIGINT NOT NULL DEFAULT '0',
`score` tinyint NOT NULL,
PRIMARY KEY (`voter_id`,`votee_id`),
KEY `votee_index` (`votee_id`)
);
オブジェクトに与えられた 1、2、3、4、および 5 つの星の投票の数を表す列を持つ、各投票オブジェクトの .csv ファイルを作成したいと考えています。
output.csv:
votee_id, count_ones, count_twos, count_threes, count_fours, count_fives
1, 3, 7, 5, 3, 2
...
このクエリを使用して、このテーブルを裏付ける生データを取得できることはわかっています。
SELECT votee_id, score, COUNT(score)
FROM scores
GROUP BY votee_id, score;
これは、私が考えたいcsv形式のデータを私に与えません:
特定のオブジェクトで表示されないスコアの 0 は表示されません。
オブジェクトの 5 つのスコアすべてを単一の行/行に結合するわけではありません (つまり、データを非正規化/ヒストグラム化します)。
mysql だけを使用して出力を作成したい。
しばらくハッキングした後、次のクエリが機能します。しかし、それはかなり非効率的であり、よりエレガントなものを見つけたり作成したりすることはできません:
SELECT votee_id, GROUP_CONCAT(COALESCE(score_count, '0') ORDER BY AllUserCrossScore.score ASC)
FROM
(SELECT votee_id, score FROM
(SELECT 1 AS score UNION ALL
SELECT 2 AS score UNION ALL
SELECT 3 AS score UNION ALL
SELECT 4 AS score UNION ALL
SELECT 5 AS score) ScoresEnum
JOIN
(SELECT DISTINCT votee_id FROM scores) DistinctIds
) AllUserCrossScore
LEFT JOIN
(SELECT votee_id, score, COUNT(score) as score_count
FROM scores
GROUP BY votee_id, score
) ScoreCounts
USING (votee_id, score)
GROUP BY votee_id;
特に、スコアをまとめるために GROUP_CONCAT を ',' と共に使用しているため、これは特にハッキリと感じます。次に、他のすべてのフィールドを ',' で結合するように mysql を他の場所で操作すると、.csv の正しい書式が得られます (操作は示されていません)。
このような場合、どうすればもっとうまくいくでしょうか?