2009-07-14 127 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