0

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

| 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在第一个和第二个表之间做 a 和 a GROUP BYby the row's Id,它为每首歌曲返回一行。

问题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。这意味着我无法处理大量用户,但现在应该没问题。

4

3 回答 3

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 演示:

于 2012-11-02T13:59:00.853 回答
0

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

SELECT * FROM  `songs` JOIN users GROUP BY song_name, ip
于 2012-11-02T12:58:08.447 回答
0

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

如果您尝试对此进行更复杂的操作GROUP BY,请按照 Quassnoi 的要求提供示例结果集。

于 2012-11-02T13:03:42.827 回答