【问题标题】:MYSQL query producing duplicate rows one one of the JOIN'sMYSQL 查询产生重复行之一的 JOIN
【发布时间】:2012-02-20 01:27:16
【问题描述】:

编辑:非常感谢 Sergey 为我解决了这个问题。一旦他将其作为答案提出,我将标记为并回答。

我的查询如下图:

 SELECT SQL_CALC_FOUND_ROWS
    songsID, song_name, artist_band_name, author, song_artwork, song_file,
    genre, song_description, uploaded_time, emotion, tempo,
    user, happiness, instruments, similar_artists, play_count,
    projects_count,
    rating, ratings_count, waveform, datasize, display_name, user_url, genre_id, 
    IF(user_ratings_count, 'User Voted', 'Not Voted') as voted 
FROM (
        SELECT  
            sp.songsID, projects_count, 
            AVG(rating) as rating,
            COUNT(rating) AS ratings_count,
            COUNT(IF(userid=$userid, 1, NULL)) as user_ratings_count

                FROM (
                    SELECT songsID, COUNT(*) as projects_count
                    FROM $sTable s
                    LEFT JOIN $sTable2 p ON s.songsID = p.songs_id

                    GROUP BY songsID) as sp

            LEFT JOIN $sTable3 r ON sp.songsID = r.songid           

            GROUP BY sp.songsID) as spr

LEFT JOIN $sTable6 gs ON gs.song_id = songsID  

JOIN $sTable s USING (songsID)
LEFT JOIN $sTable5 q ON s.user = q.ID   

虽然此查询返回来自各种表(均指定为 $sTable、$sTable2、$sTable3 等)的所有信息,但它给了我基于 $sTable6 的重复行。

这只发生在 $sTable6 JOIN 就位的情况下,从底部倒数第三行:

LEFT JOIN $sTable6 gs ON gs.song_id = songsID  

删除此行后一切正常。但是,我需要检索此信息以便通过“genre_id”提供动态过滤。目前,它从 $sTable 中检索所有行以及来自其他各种表的所有相应信息,但还会重新打印 $sTable 中与 $sTable6 共享 song_id/songsID 的任何行。

如何防止这种情况发生?

【问题讨论】:

  • 我可以想到那里的连接顺序,并记住左连接是外连接,如果找不到匹配项,将返回空值。或者使用 group by 来摆脱重复,但也许是最后的手段。希望对您有所帮助。
  • 你用的是哪个版本的mysql?我发现了这一点——阅读 5.1 上的文档 自然连接或使用连接的列可能与以前不同。具体来说,冗余的输出列不再出现,SELECT * 扩展的列顺序可能与之前不同。
  • 谢谢谢尔盖。我实际上已经尝试过使用 GROUP BY。虽然这确实按预期删除了重复项,但由于某种原因,它稍后也会在我的 WHERE 子句中导致语法错误。我真的不知道为什么
  • 我正在使用 MYSQL 版本 5.0.92...如果需要,可以升级我的版本
  • 所以这可能是 5.1 之前的版本的问题。我建议您升级,尽管它们的意思是“以前”一词的意思是“在 MySQL 5.0.12 之前”。情况可能并非如此,但我仍然建议这样做。

标签: mysql database database-design join


【解决方案1】:

您在 LEFT JOINed 表中有重复的 song_id。我使用类似以下的方法将该 JOIN 限制为只有一个匹配的记录:

已编辑:

LEFT JOIN $sTable6 gs ON gs.song_id = songsID AND gs.MYUNIQUECOLUMN IN (SELECT MYUNIQUECOLUMN FROM $sTable6 WHERE song_id = songsID ORDER BY MYUNIQUECOLUMN LIMIT 1)

【讨论】:

  • 感谢 ElJay 看起来不错!不幸的是,我无法测试它,因为我的 mysql 升级完全失败了!令人担忧的是,我在重新安装它时遇到了麻烦,因为我不断地从 remi repo 中找到包! 恐慌
  • @gordyr,除了 Gentoo 之外,我不熟悉 MySQL 安装,所以我无法帮助你。我确实修复了上面的 SQL(它不会像以前那样解决任何问题)
  • 这将使您仅加入 1 个 songId 在这种情况下首先订购。你确定要这样做吗?在这种情况下,我根本看不到查询的意义,因为您需要为每个选定的 songId 提供genreId,而不是从表6中获得的唯一第一个。我弄错了吗?
  • 没问题,我相信我很快就会把它整理好...一旦我这样做了,我已经测试了你的解决方案,我会将问题标记为已回答。非常感谢。 :-)
  • 您是如何执行升级的?你在使用 CentOS/RHEL 吗?
猜你喜欢
  • 1970-01-01
  • 2015-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 2013-02-23
相关资源
最近更新 更多