我尝试将以下表格合并到一个查询中(最终目标是从 PHP 输出 CSV 文件):
用户
id, name, email
例如。数据
1, John, email@email.com
2, Jane, email@email.com
问题 - 问题的静态列表,每个问题都是存储为“属性”的 3 种类型之一,即单个字母 [A、B、C]
id, text, attribute
例如。数据
1, How cool are dogs?, A
2, How cool are cats?, B
3, How cool are fish?, A
4, How cool are mice?, C
5, How cool are birds?, B
users_questions - 其中答案是整数 [1-5]
id, user_id, question_id, answer
例如。数据
1, 1, 1, 2
2, 1, 2, 5
3, 1, 3, 1
4, 1, 4, 1
5, 1, 5, 4
6, 2, 1, 4
7, 2, 2, 1
8, 2, 3, 3
9, 2, 4, 2
10, 2, 5, 2
期望的结果:
我试图将所有这些数据与按属性分组的每个用户的问题合并为一个查询,因此输出格式如下:
users.id, users.name, users.email , A_question_total, B_question_total, C_question_total
1, John , email@email.com, 3, 9, 1
2, Jane , email@email.com, 7, 3, 2
我目前拥有的:
我已经尝试过下面的查询,这些查询几乎都能满足我的需求:
我可以选择连接在一起的所有内容,但这会重复用户和问题,并且不会按用户/属性提供问题总数:
Select * FROM users
JOIN users_questions ON users.id = users_questions.user_id
JOIN questions ON questions.id = users_questions.question_id;
我还可以按用户/属性选择所有问题总数,但随后我必须单独获取用户,然后在 PHP 中将它们连接在一起。
SELECT questions.attribute, users_questions.user_id, SUM(users_questions.answer) AS `total` FROM `questions` LEFT OUTER JOIN `users_questions` ON questions.id = users_questions.`question_id` GROUP BY users_questions.user_id, questions.attribute;
我想知道是否有一种方法可以通过复杂的连接、分组、子查询等在一个查询中完成这一切。我正在努力了解如何组合上述两个查询,并转换每个用户列中本质上单独计算的总“行”。
这是示例数据的 SQL 转储:
DROP TABLE IF EXISTS `questions`;
CREATE TABLE `questions` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`text` varchar(30) DEFAULT NULL,
`attribute` enum('A','B','C') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `questions` (`id`, `text`, `attribute`)
VALUES
(1,'How cool are dogs?','A'),
(2,'How cool are cats?','B'),
(3,'How cool are fish?','A'),
(4,'How cool are mice?','C'),
(5,'How cool are birds?','B');
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
`email` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `users` (`id`, `name`, `email`)
VALUES
(1,'John','email@email.com'),
(2,'Jane','email@email.com');
DROP TABLE IF EXISTS `users_questions`;
CREATE TABLE `users_questions` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned DEFAULT NULL,
`question_id` int(11) unsigned DEFAULT NULL,
`answer` tinyint(1) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `users_questions` (`id`, `user_id`, `question_id`, `answer`)
VALUES
(1,1,1,2),
(2,1,2,5),
(3,1,3,1),
(4,1,4,1),
(5,1,5,4),
(6,2,1,4),
(7,2,2,1),
(8,2,3,3),
(9,2,4,2),
(10,2,5,2);
感谢任何帮助!
最佳答案
我认为这个查询( SQLFiddle )会解决您的问题:
Select u.id, u.name, u.email,
SUM(case q.attribute when 'A' then uq.answer else 0 end) as A_question_total,
SUM(case q.attribute when 'B' then uq.answer else 0 end) as B_question_total,
SUM(case q.attribute when 'C' then uq.answer else 0 end) as C_question_total
FROM users u
JOIN users_questions uq ON u.id = uq.user_id
JOIN questions q ON q.id = uq.question_id
group by u.id
输出:
id name email A_question_total B_question_total C_question_total
1 John email@email.com 3 9 1
2 Jane email@email.com 7 3 2
关于MySQL 将 3 个测验表与按属性/用户计算的总数连接起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49970653/