enter image description here SELECT *来自user
所在的ID(从user
按性别分组的group_concat(id)中选择);
我想要以下结果
UPDATE `user` SET average_age = (SELECT AVG(score) FROM `score` WHERE id IN (select user_id from `score`))
从user
WHERE ID IN(1,2,3)中选择AVG(分数);
从ID为(2,5)的user
中选择AVG(分数);
......
如何使用group_concat函数IN IN()实现批处理和新数据?
数据:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`score` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'man', 21, 'Tom', 300);
INSERT INTO `user` VALUES (2, 'man', 23, 'Jerry', 350);
INSERT INTO `user` VALUES (3, 'woman', 18, 'Mary', 400);
INSERT INTO `user` VALUES (4, 'woman', 12, 'Lily', 450);
INSERT INTO `user` VALUES (5, 'woman', 16, 'Jasmine', 320);
INSERT INTO `user` VALUES (6, 'woman', 16, 'Jasmine', 420);
INSERT INTO `user` VALUES (7, 'woman', 18, 'Violet', 500);
INSERT INTO `user` VALUES (8, 'woman', 18, 'Violet', 580);
INSERT INTO `user` VALUES (9, 'woman', 20, 'Sophia', 520);
INSERT INTO `user` VALUES (10, 'man', 22, 'Charlotte', 450);
INSERT INTO `user` VALUES (11, 'man', 18, 'Jackson', 400);
SET FOREIGN_KEY_CHECKS = 1;
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`average_score` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of score
-- ----------------------------
INSERT INTO `score` VALUES (1, '1,2,3', NULL);
INSERT INTO `score` VALUES (2, '2,5', NULL);
INSERT INTO `score` VALUES (3, '1,3,4,5', NULL);
INSERT INTO `score` VALUES (4, '2,3,6,8,11', NULL);
INSERT INTO `score` VALUES (5, '2,3,6', NULL);
INSERT INTO `score` VALUES (6, '2,3,4,5,6,7', NULL);
INSERT INTO `score` VALUES (7, '2,3,4,5,6,7', NULL);
INSERT INTO `score` VALUES (8, '3,4,5,9,10', NULL);
INSERT INTO `score` VALUES (9, '2', NULL);
INSERT INTO `score` VALUES (10, '3,5,8,9,10', NULL);
INSERT INTO `score` VALUES (11, '3,5,8,9,10', NULL);
SET FOREIGN_KEY_CHECKS = 1;
答案 0 :(得分:0)
首先,我想纠正问题标题所表示的基本误解
SELECT *
FROM user
WHERE name IN (select group_concat(name) from user GROUP BY sex)
(我将id更改为name以更好地说明我的观点)
此查询在概念上等同于:
SELECT *
FROM user
WHERE name IN (
'John,Tim,Dave',
'Sarah,Sally,Anne'
)
这是合法语法,但几乎可以肯定不是您想要的。您不会通过提供一个字符串输入值(例如,上面用逗号分隔)来编写使用IN的查询,而是向IN提供这样的值列表:
SELECT *
FROM user
WHERE name IN (
'John','Tim','Dave',
'Sarah','Sally','Anne'
)
这是一个微妙的但从根本上来说是巨大的区别,如果您没有看到它,请给我评论
您要查询的内容应该只是要提供给IN的各个值的查询输出列表,而不是CSV字符串或CSV字符串列表。因此,您的查询应为:
SELECT *
FROM user
WHERE name IN (
select name from othertable...
)
由于您的实际问题,您似乎想用另一个表的摘要数据更新一个表:
UPDATE
`user` u
INNER JOIN
(SELECT user_id, AVG(score) avgscore FROM `score` GROUP BY user_id) a
ON u.id = a.user_id
SET
u.average_age = a.avgscore
我们按人创建分数摘要,将其加入用户表并更新用户表
但是我要警告您不要这样做,因为您存储的数据可能会不同步。不用将平均值存储在用户表中,只需将数据保留在得分表中,并在每次需要时重新计算平均值:
SELECT *
FROM
`user` u
INNER JOIN
(SELECT user_id, AVG(score) avgscore FROM `score` GROUP BY user_id) a
ON u.id = a.user_id
这也可以写成:
SELECT u.*, AVG(s.score) as avgscore
FROM
`user` u
INNER JOIN
`score` s
ON u.id = s.user_id
GROUP BY
<list of columns in u>
我倾向于避免这种模式偏向于“先在子查询中先分组,然后再连接”,因为如果您有两个表要连接并汇总第三个表,则通过导致值重复,可以更容易破坏第二个表的统计信息。相比之下,分组作为子类提供了联接,其中a中只有一行可以与b,c等中的一行匹配。哦,逐组写出分组确实很麻烦/无聊