我有两张表允许用户请求歌曲。当然,多个用户可以请求一首歌:
| 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
,并在行GROUP BY
之间进行Id
,为每首歌返回一行。
问题:GROUP BY
会在未分组的字段上返回不可预测的值。这是众所周知的。但是,如果此组中存在此IP,我如何确保SELECT
返回包含特定IP的行?如果IP不存在,则SELECT
可以返回该组的任何其他行。
非常感谢!
更新:我需要在列表中显示歌曲,而不管有多少用户(甚至根本没有用户)请求它。所以SELECT肯定需要为每首歌返回一行。但是,例如,具有IP 3.3.3.3的用户试图请求song1(已经由他请求),我希望查询返回:
| 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.这意味着我无法处理大量用户,但现在它应该没问题。
答案 0 :(得分:1)
目前还不清楚你想要什么?表中没有要求的日期。如果没有日期,你怎么知道特定歌曲何时被请求。
Select Songs.id, Songs.Song_name, requested_songs.By_IP from Songs INNER JOIN requested_songs on Songs.id = requested_songs.Requested_id Group BY requested_songs.Requested_id order by requested_songs.Requested_id ASC ;
<强> SQLFiddle Demo: 强>
答案 1 :(得分:0)
只需使用Song_Name和By_IP进行分组。喜欢这个
SELECT * FROM `songs` JOIN users GROUP BY song_name, ip
答案 2 :(得分:0)
你确定你没有过度思考你的解决方案吗?如果您只想消除重复项,只需在第二个表的两列上放置一个UNIQUE
索引。
如果您尝试使用GROUP BY
执行更复杂的操作,请提供Quassnoi请求的示例结果集。