2009-07-14 87 views
0

我使用此查询来显示歌曲列表并显示哪些歌曲已被用户点击为收藏夹。加入查询返回奇数结果

$query = mysql_query(
    sprintf(" 
    SELECT 
     s.*, 
     UNIX_TIMESTAMP(`date`) AS `date`, 
     f.userid as favoritehash 
    FROM 
     songs s 
    LEFT JOIN 
     favorites f 
    ON 
     f.favorite = s.id 
     AND f.userid = %s", 
    $userhash) 
); 

songs表被设置为:id artist title duration等等,等等

favorites的表是设置为:id favorite userid

userid是存储在cookie中的哈希值来引用一个唯一的用户。

查询工作正常,但由于某种原因,如果我在一个浏览器中将歌曲标记为最爱。然后在另一个浏览器中将同一首歌曲标记为收藏夹,以模拟多个用户,这首歌曲将显示两次...每次一次它被标记为最喜欢的,但最喜欢的指示符仍然正确显示< 3。

任何想法?

好了,它通过removign sprintf()工作,但好奇地知道为什么这是如果任何人有任何想法。

回答

1

您正在使用sprintf和%S(串),但你不能放入引号内生成的字符串值。如果用户标识是一个字符串,那么您需要用引号括起来,否则使用%d而不是%s。由于它在删除sprintf时工作正常,这似乎是问题所在。

1

我有一个类似的问题,我认为如果您将And F.userid =%s更改为Where f.userid =%s,它应该修复它。

+0

我实际上删除了整个sprintf部分,它似乎工作完美。 – ian 2009-07-14 12:49:03

0

我认为你的ON条款是错误的。

试试这个:

ON f.favorite = s.id 
WHERE f.userid = %s 
+0

我需要它是因为我得到了确保最喜欢的项目匹配歌曲行中的当前歌曲和活动用户? – ian 2009-07-14 12:50:13

+0

好吧,这就是我所关心的 – knittl 2009-07-14 14:06:05

0

我认为,上述建议实际上打败LEFT JOIN,使其充当INNER JOIN; f.userid有时会是NULL,并且NULL总是会比较为false

我会先看看favorites表的内容。如果我了解您的架构,则可能需要在favoriteuserid之上建立favorites上的唯一密钥,以确保给定用户只能收藏每首歌曲一次。也就是说,您可能会得到重复的行,从而导致重复的结果。

0

由于您正在使用“左连接”,因此我假设您想要所有歌曲的列表,并且希望用户的最爱可以轻松区分。即是这样的:

song1 details | date | null 
song2 details | date | userhash (favorite) 
song3 details | date | null 

尝试以下操作:

SELECT s.*, UNIX_TIMESTAMP(`date`) AS `date`, f.userid as favoritehash 
FROM 
    songs s 
LEFT JOIN 
    (SELECT userid, favorite FROM favorites WHERE userid = %s) f 
ON 
    f.favorite = s.id