MySQL GROUP_CONCAT 防止不必要的重复
Posted
技术标签:
【中文标题】MySQL GROUP_CONCAT 防止不必要的重复【英文标题】:MySQL GROUP_CONCAT prevent unnecessary duplicates 【发布时间】:2017-12-18 09:04:36 【问题描述】:我正在从本地 WordPress (bbPress) 安装导出一些数据,并且在我的 GROUP_CONCAT 列(数据库中不存在)中遇到重复数据。
这是查询:
SELECT
a.`ID`, a.`post_date`, a.`post_content`, a.`post_title`,
a.`post_status`, a.`post_name`, a.`post_type`, a.`post_parent`,
GROUP_CONCAT(d.`meta_key` SEPARATOR '|') AS `post_meta_keys`,
GROUP_CONCAT(d.`meta_value` SEPARATOR '|') AS `post_meta_values`,
b.`user_login`, b.`user_pass`, b.`user_nicename`, b.`user_email`,
b.`user_registered`, b.`display_name`,
GROUP_CONCAT(c.`meta_key` SEPARATOR '|') AS `user_meta_keys`,
GROUP_CONCAT(c.`meta_value` SEPARATOR '|') AS `user_meta_values`
FROM
`wp_posts` a
INNER JOIN
`wp_users` b ON a.`post_author` = b.`ID`
INNER JOIN
`wp_usermeta` c ON a.`post_author` = c.`user_id`
INNER JOIN
`wp_postmeta` d ON a.`ID` = d.`post_id`
WHERE
`post_type` = 'forum' OR
`post_type` = 'topic' OR
`post_type` = 'reply'
GROUP BY
a.`ID`
我正在尝试获取一个大视图,其中包含帖子、其元信息以及每一行中的作者信息。一切都很好,除了 GROUP_CONCAT 列有多个重复项。例如:从结果集的第一行开始 - user_meta_keys
列具有以下值:
[0] => nickname
[1] => first_name
[2] => last_name
[3] => description
[4] => rich_editing
[5] => comment_shortcuts
[6] => admin_color
[7] => use_ssl
[8] => show_admin_bar_front
[9] => locale
[10] => wp_capabilities
[11] => wp_user_level
[12] => dismissed_wp_pointers
[13] => show_welcome_panel
[14] => session_tokens
[15] => wp_dashboard_quick_press_last_post_id
[16] => community-events-location
[17] => managenav-menuscolumnshidden
[18] => metaboxhidden_nav-menus
[19] => nav_menu_recently_edited
[20] => users_per_page
[21] => wp__bbp_topic_count
[22] => wp__bbp_reply_count
[23] => nickname
[24] => first_name
[25] => last_name
[26] => description
[27] => rich_editing
[28] => comment_shortcuts
[29] => admin_color
[30] => use_ssl
[31] => show_admin_bar_front
[32] => locale
[33] => wp_capabilities
[34] => wp_user_level
[35] => dismissed_wp_pointers
[36] => show_welcome_panel
[37] => session_tokens
[38] => wp_dashboard_quick_press_last_post_id
[39] => community-events-location
[40] => managenav-menuscolumnshidden
[41] => metaboxhidden_nav-menus
[42] => nav_menu_recently_edited
[43] => users_per_page
[44] => wp__bbp_topic_count
[45] => wp__bbp_reply_count
[46] => nickname
[47] => first_name
[48] => last_name
[49] => description
[50] => rich_editing
[51] => comment_shortcuts
[52] => admin_color
[53] => use_ssl
[54] => show_admin_bar_
昵称重复了 3 次,许多其他字段也是如此。我已经进行了一些搜索,看起来其他人也经历过这种情况。有些人通过在分组列上使用“DISTINCT”来解决它 - 但这对我不起作用,因为某些值实际上是重复的。
所以我的问题是:
1) 有人可以向我解释为什么 GROUP_CONCAT 列有这么多重复项以及查询是否写错 - 我至少会计算出“键”列和“值”列之间匹配的计数 - 但它们也不要。
2) 可以调整查询以完成我要查找的内容吗?
感谢您的宝贵时间!
-- 编辑#1-- 好吧,一个错误是我忘记在 mysql 中将 GROUP_CONCAT 限制设置得更高——所以现在我正在升级,我认为我越来越接近了。
-- 编辑#2-- 看起来 GROUPS 的重复行数与每个备用表中的行数一样多?含义... postmeta 表中有 8 行与 post id 匹配,因此 usermeta 结果中有 8 个重复的组...或者 usermeta 表中有 23 行与用户 id 匹配,因此有 23 个重复的组在 postmeta 结果中...我目前仍在寻找纠正此问题的方法。
-- 编辑#3--
这是添加的 MCVE:
-- 原始查询:http://sqlfiddle.com/#!9/386b98/2
-- 更新查询:http://sqlfiddle.com/#!9/386b98/3
【问题讨论】:
见:Why should I provide an MCVE for what seems to me to be a very simple SQL query? @Strawberry - 你是对的 - 我会为所有未来的 sql 问题添加一个 MCVE - 我会尽快在此处添加一个,以便访问者可以看到两者之间的区别查询 【参考方案1】:出现重复问题是因为我不知道在 SQL 中处理 JOINS 的方式 - (我仍在学习) - 这个堆栈溢出答案真的帮助了我(Martin Smith)sql joins as venn diagram
看起来当它连接user_meta
表的多行数据时,每个post_meta
表行被连接了很多次,反之亦然。所以我目前的解决方案是从这两个表中删除 INNER JOIN 并将它们简单地添加到语句的 SELECT 部分 - 就像这样:
SELECT
a.`ID`, a.`post_date`, a.`post_content`, a.`post_title`,
a.`post_status`, a.`post_name`, a.`post_type`, a.`post_parent`,
(SELECT GROUP_CONCAT(d.`meta_key` SEPARATOR '|') FROM `wp_postmeta` d
WHERE d.`post_id` = a.`ID`) AS `post_meta_keys`,
(SELECT GROUP_CONCAT(d.`meta_value` SEPARATOR '|') FROM `wp_postmeta` d
WHERE d.`post_id` = a.`ID`) AS `post_meta_values`,
b.`user_login`, b.`user_pass`, b.`user_nicename`, b.`user_email`,
b.`user_registered`, b.`display_name`,
(SELECT GROUP_CONCAT(c.`meta_key` SEPARATOR '|') FROM `wp_usermeta` c
WHERE c.`user_id` = a.`post_author`) AS `user_meta_keys`,
(SELECT GROUP_CONCAT(c.`meta_value` SEPARATOR '|') FROM `wp_usermeta` c
WHERE c.`user_id` = a.`post_author`) AS `user_meta_values`
FROM
`wp_posts` a
INNER JOIN
`wp_users` b ON a.`post_author` = b.`ID`
WHERE
`post_type` = 'forum' OR
`post_type` = 'topic' OR
`post_type` = 'reply'
GROUP BY a.`ID`
我不知道你能做到这一点 - 这会产生更快/更清晰的结果。
-- 工作示例:http://sqlfiddle.com/#!9/386b98/3
【讨论】:
以上是关于MySQL GROUP_CONCAT 防止不必要的重复的主要内容,如果未能解决你的问题,请参考以下文章