2014-04-09 210 views
0

我有2個表:連接2個MySQL查詢

用戶

ID |用戶

喜歡

ID |所有者|日期

而這個查詢:

$owner_result = $connector->query("SELECT id FROM users"); 
while($owner = $connector->fetchArray($owner_result)) 
{ 
$rs = $connector->query("SELECT count(id) AS num FROM likes 
WHERE date > DATE_SUB(NOW(), INTERVAL 1 WEEK) 
AND owner='$owner[id]' 
ORDER BY num DESC LIMIT 5"); 
while($rw = $connector->fetchArray($rs)) 

{echo "This owner ($owner[id]) has $rw[num] likes this week";} 

} 

我想我做的是回到我5 users.id與中行最大ammount的行喜歡表。 我的查詢返回的只是$ owner [id],但不是每個人都喜歡。而且我想查詢的性能是非常低的,以及因爲我的查詢檢查喜歡的量爲每users.id喜歡表,但它可能是喜歡不包含一些用戶。 ID

任何解決我的問題或改善我的查詢的建議將非常受歡迎。 謝謝。

回答

1

我認爲,一個單一的查詢會得到你指定的結果,例如:

SELECT u.id 
    , COUNT(t.owner) AS cnt_likes 
    FROM users u 
    JOIN likes t 
    ON t.owner = u.id 
WHERE t.date > DATE_SUB(NOW(), INTERVAL 1 WEEK) 
GROUP BY u.id 
ORDER BY 2 DESC 
LIMIT 5 

likes表中的適當的索引可以提高性能:

... ON likes (owner, date) 

或者,這會給出一個等效結果,可能具有(稍微)更好的性能:

SELECT u.id 
    , t.cnt_likes 
    FROM users u 
    JOIN (SELECT s.owner 
       , COUNT(1) AS cnt_likes 
      FROM likes s 
      WHERE s.date > DATE_SUB(NOW(), INTERVAL 1 WEEK) 
      GROUP BY s.owner 
     ) t 
    ON t.owner = u.id 
ORDER BY t.cnt_likes DESC 
LIMIT 5 

你會得到,如果你是保證在likes表中的列owner的所有值實際上id值在user表...因爲你可以避開加入到用戶表,並獲得更好的性能從likes表全部結果:

SELECT s.owner 
    , COUNT(1) AS cnt_likes 
    FROM likes s 
WHERE s.date > DATE_SUB(NOW(), INTERVAL 1 WEEK) 
GROUP BY s.owner 
ORDER BY cnt_likes DESC 
LIMIT 5 

但是,該查詢並沒有做檢查,以驗證從owner列中返回的值存在作爲user表的id列。

+0

謝謝!正在工作 –

+0

@Valerius Mazare:你的直覺是對的;運行單個查詢並從MySQL服務器獲取單個結果集通常要比運行多個查詢執行「循環」更有效。 (這也使得代碼更簡潔。)但是,它並不總是*更高效;有一些邊界情況下,運行優化的單例查詢實際上可能比具有可怕訪問計劃的怪異查詢更有效,但這比規則更多例外。) – spencer7593

1

您必須在第二個查詢中由所有者創建一個組。如果不先將它們分組,則無法對行進行計數。

$owner_result = $connector->query("SELECT id FROM users"); 
while($owner = $connector->fetchArray($owner_result)) 
{ 
$rs = $connector->query("SELECT count(id) AS num FROM likes 
WHERE date > DATE_SUB(NOW(), INTERVAL 1 WEEK) 
AND owner='$owner[id]' 
Group BY owner 
ORDER BY num DESC LIMIT 5"); 
while($rw = $connector->fetchArray($rs)) 

{echo "This owner ($owner[id]) has $rw[num] likes this week";} 

} 
+0

謝謝。但它顯示我只有2個條目,而不是期望的5. –

+0

也許數據限制到2在這一點上。 –

1

你應該加入這兩個表,因此您可以在一個單一的聲明讓您的數據:

SELECT 
    users.id, 
    COUNT(likes.id) AS mylikes  -- specify a name for the computed column 
FROM users 
INNER JOIN likes 
ON users.id = likes.owner 
WHERE date > DATE_SUB(NOW(), INTERVAL 1 WEEK) 
GROUP BY users.id 
ORDER BY COUNT(likes.id) DESC  -- MySQL would allow the alias name 
LIMIT 5       -- because you want the top 5 

如果有一條領帶,那你將失去一個記錄(或更多)。

+0

不幸的是,它不顯示我的東西 –

+1

@ValeriuMazare我創建了一個SQL小提琴:http://sqlfiddle.com/#!2/2c63f3/2 – VMai