从 GROUP BY 组中选择具有特定内容的行

Posted

技术标签:

【中文标题】从 GROUP BY 组中选择具有特定内容的行【英文标题】:Select a row with specific content from a GROUP BY group 【发布时间】:2012-11-02 12:39:47 【问题描述】:

我有两个表允许用户请求歌曲。当然,多个用户可以请求一首歌曲:

| Id | Song_Name |       | Requested_Id |  By_IP  |
+====+===========+       +==============+=========+
| 1  |   song1   |       |      1       | 1.1.1.1 |
| 2  |   song2   |       |      1       | 2.2.2.2 |
| 3  |   song3   |       |      1       | 3.3.3.3 |
                         |      2       | 2.2.2.2 |

为了防止一个用户多次请求一首歌曲(滥用),我需要检查某首歌曲是否已经被正在尝试再次请求的用户请求。所以我在第一张和第二张桌子之间做一个LEFT JOIN,并在行的Id 旁边做一个GROUP BY,它为每首歌返回一行。

问题GROUP BY 在未分组的字段上返回不可预测的值。这是众所周知的。但是,如果该 IP 存在于该组中,我如何确保 SELECT 返回包含特定 IP 的行?如果IP不存在,则SELECT可以返回该组的任何其他行。

非常感谢!

更新:我需要在列表中显示这首歌,与有多少用户(甚至根本没有用户)请求它无关。所以 SELECT 肯定需要为每首歌曲返回一行。但是,如果 IP 3.3.3.3 的用户尝试请求歌曲 1(他已经请求过),我希望查询返回以下内容:

| Id | Song_Name |  By_IP  |
+====+===========+=========+
| 1  |   song1   | 3.3.3.3 |  (3.3.3.3 in case it exists, otherwise anything else)
| 2  |   song2   | 2.2.2.2 |

我还需要与其他请求 (IP) 进行分组,因为我还需要获取每首歌曲的全部请求数。因此我使用 Count()。

解决方法:因为做我需要的事情似乎很复杂(如果可能的话),我现在正在使用一种解决方法。我正在使用 GROUP_CONCAT() 聚合函数。这为我提供了该组的所有 IP,以“,”分隔。所以我可以搜索我正在搜索的那个是否已经存在。唯一的缺点是,这个返回字符串的(默认)最大长度是 1024。这意味着我无法处理大量用户,但现在应该没问题。

【问题讨论】:

您希望查询返回什么?请发布示例结果集。 【参考方案1】:

目前还不清楚你想要什么?表中没有要求的日期。没有日期,您如何知道何时请求了特定歌曲。

选择 Songs.id、Songs.Song_name、requested_songs.By_IP 从歌曲 INNER JOIN 请求_歌曲 在 Songs.id = requested_songs.Requested_id Group BY requested_songs.Requested_id 按 request_songs.Requested_id ASC 排序 ;

SQLFiddle Demo:

【讨论】:

这会返回我对某首歌曲的所有请求。这意味着多行。但我每首歌只需要一行。 嗨!我不需要知道“何时”请求了一首歌曲,我只需要知道特定用户是否已经请求了那首歌曲。为此,我将请求用户的 IP 和歌曲 ID 一起输入到第二个表中(见上文)。【参考方案2】:

您确定您没有过度考虑您的解决方案吗?如果您只想消除重复项,只需在第二个表的两列上都放置一个UNIQUE 索引。

如果您想用 GROUP BY 做一些更复杂的事情,请按照 Quassnoi 的要求提供一个示例结果集。

【讨论】:

【参考方案3】:

只需按 Song_Name 和 By_IP 分组即可。像这样

SELECT * FROM  `songs` JOIN users GROUP BY song_name, ip

【讨论】:

这对我不起作用,因为我仍然需要计算任何 Id 的请求总数。因此,我需要使用 GROUP BY 和 Count() 的可能性另一方面,据我所知,JOIN 仅在两个表中都存在 Id 的情况下才连接行。

以上是关于从 GROUP BY 组中选择具有特定内容的行的主要内容,如果未能解决你的问题,请参考以下文章

在特定列 postgres 中选择具有最大值的组中的行

SQL SELECT GROUP BY并加入具有特定值的行

从Oracle SQL中的每个组中选择具有最大值的行[重复]

SQL Server:根据多个条件从组中选择特定行

GROUP BY 如果组中至少一个值满足条件,则创建组

在 SQL 中选择不在 Group By 中的列