2012-11-02 36 views
0

我有两个允许用户请求歌曲的表格。当然,一首歌可以由多个用户请求:从GROUP BY组中选择包含特定内容的行

| 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在未分组的字段上返回不可预知的值。这是已知的。但是如何确保SELECT返回包含特定IP的行,以防该组存在此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.这意味着我不能处理大量的用户,但现在应该没问题。

+3

你怎么从你的查询期望返回?请发布一个示例结果集。 – Quassnoi

回答

0

只需使用Song_Name和By_IP进行分组即可。像这样

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

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

0

你确定你没有超越你的解决方案吗?如果您只想消除重复项,只需在两列的第二张表中输入UNIQUE索引即可。

如果您想要对GROUP BY做更复杂的操作,请按照Quassnoi的要求提供一个示例结果集。

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:

+0

这将返回我为某首歌曲获得的所有请求。这意味着多行。但是我每首歌只需要一行。 – Bernd

+0

我编辑了答案。请检查。 – Anam

+0

嗨!我不需要知道“何时”播放了歌曲,我只需要知道某个特定用户是否已经请求了某首歌曲。要做到这一点,我输入请求用户的IP,将歌曲的ID输入到第二个表格中(请参阅上文)。 – Bernd