MySQL GROUP_CONCAT可以防止不必要的重复

时间:2017-07-13 14:05:02

标签: mysql sql duplicates group-concat

我正在通过从本地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`

我试图在每一行中获得一个包含Post,其元信息和作者信息的大视图。一切都很好,除了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

1 个答案:

答案 0 :(得分: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