简体   繁体   English

连接查询返回奇数结果

[英]join query returning odd results

I use this query to display a list of songs and show what songs have been clicked as a favorite by a user. 我使用此查询来显示歌曲列表,并显示用户单击了哪些歌曲作为收藏。

$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)
);

The songs table is setup as: id artist title duration etc. etc. songs表设置为: id artist title duration等。

The favorites table is setup as: id favorite userid favorites表设置为: id favorite userid

The userid is a hashed value stored in a cookie to reference a unique user. userid是存储在cookie中以引用唯一用户的哈希值。

The query works fine but for some reason if I mark a song as a favorite in one browser. 该查询工作正常,但是由于某种原因,如果我在一个浏览器中将歌曲标记为收藏,则出于某种原因。 And then mark the same song as favorite in another browser to simulate multiple users the song will be displayed twice... once for each time it is marked favorite but the favorite indicator a <3 will still display correctly. 然后在同一浏览器中将同一首歌曲标记为“我的收藏”以模拟多个用户,这首歌曲将显示两次...每次将其标记为“我的收藏”,但“ <3”收藏夹指示符仍会正确显示。

Any ideas? 有任何想法吗?

Well got it to work via removign the sprintf() but curious to know why this is if anyone has any ideas. 可以通过删除sprintf()使其正常工作,但是很好奇为什么这是任何人都有想法的原因。

我有一个类似的问题,我想如果您将And F.userid =%s更改为f.userid =%s,它应该解决此问题?

You are using sprintf and %s (string), but you are not enclosing the resulting string value in quotes. 您正在使用sprintf和%s(字符串),但没有将结果字符串值括在引号中。 If the user ID is a string, then you need to enclose it in quotes, otherwise use %d instead of %s. 如果用户ID是字符串,则需要将其用引号引起来,否则请使用%d代替%s。 Since it works fine when you remove sprintf, that would seem to be the problem. 因为当您删除sprintf时它工作正常,这似乎是问题所在。

i think your ON -clause is wrong. 我觉得你ON -clause是错误的。

try this instead: 试试这个代替:

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

I believe that the previous suggestions would actually defeat the LEFT JOIN , causing it to act as an INNER JOIN ; 我相信先前的建议实际上会击败LEFT JOIN ,使其成为INNER JOIN ; f.userid would sometimes be NULL , and NULL always compares as false . f.userid有时为NULL ,并且NULL总是比较为false

I would start by looking at the contents of the favorites table. 我将从查看“ favorites表的内容开始。 If I understand your schema, you might want to establish a unique key on favorites over favorite and userid to make sure that a given user can only favorite each song once. 如果我了解您的模式,您可能希望在favorites favorite上建立一个唯一键,而不是favoriteuserid ,以确保给定用户只能将每首歌曲收藏一次。 That is, you may be getting duplicate rows, and hence duplicate results. 也就是说,您可能会得到重复的行,从而导致重复的结果。

Since you are using a 'left join' I am assuming that you want a list of all the songs and that you want the users favorites to be easily distinguishable. 因为您使用的是“左联接”,所以我假设您想要所有歌曲的列表,并且希望用户的收藏夹易于区分。 ie something like this: 即这样的事情:

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

Try the following: 请尝试以下操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM