2017-02-12 104 views
0

我試圖從Sponsor表中加入到Company表中隨機獲取單個行。以下查詢差不多的作品,但有時會返回一個NULL贊助商。左加入單個隨機記錄MySQL

任何人都可以看到我在做什麼錯在這裏?

SELECT C.ID AS CompID, C.Name AS CompName, S.ID AS SponID, S.Name AS SponName 
FROM Company C 
    LEFT JOIN Sponsor S ON S.ID = (SELECT ID FROM Sponsor WHERE Company = C.ID ORDER BY RAND() LIMIT 1) 

數據樣本:在下面的一個

Company Table 
| ID | Name  | 
| 1 | MyCompany | 

Sponsor Table 
| ID | Company | Name | 
| 1 |  1 | Bruce | 
| 2 |  1 | John | 

查詢結果:

| CompID | CompName | SponsID | SponName | 
| 1 | MyCompany | 1 | Bruce | 

| CompID | CompName | SponsID | SponName | 
| 1 | MyCompany | 2 | John | 

| CompID | CompName | SponsID | SponName | 
| 1 | MyCompany | NULL | NULL | 
+0

如果有人甚至可以告訴我這是爲什麼發生,這將是巨大的。 –

+0

顯示樣本數據。如果一個公司沒有贊助商,你就無能爲力。 –

+0

在這種情況下,公司有2個贊助商。查詢將返回Sponsor1,Sponsor2或NULL。 –

回答

1

由於RAND()您的子查詢不是確定性的,因此會針對Sponsor表中的每一行執行,並且每次都會回退隨機ID,該ID可能與當前行的ID匹配。所以不僅有可能,沒有行將與隨機ID匹配。也可能有多行。

對於具有兩個發起樣本數據子查詢可以返回如下因素值:

  • (1,1)將在第一行匹配(1 = 1,2 = 1)
  • (1,2 )將匹配兩行(1 = 1,2 = 2)
  • (2,1)將匹配沒有行(1 = 2,2 = 1)
  • (2,2)將匹配第二行(1 = 2,2 = 2)

爲了保證su bquery只執行一次,你可以使用它的SELECT子句。然後用Sponsor表連接的結果作爲派生表:

SELECT C.*, S.Name AS SponName 
FROM (
    SELECT C.ID AS CompID, C.Name AS CompName, (
     SELECT ID FROM Sponsor WHERE Company = C.ID ORDER BY RAND() LIMIT 1 
    ) as SponID 
    FROM Company C 
) C 
LEFT JOIN Sponsor S ON S.ID = C.SponID 

演示:http://rextester.com/LSSJT25902

+0

我不理解。WHERE子句不是隻過濾我需要的行,並且LIMIT 1只是獲取第一條記錄? –

+0

您的WHERE過濾器不是靜態的,而是在每次調用時都是動態的和隨機的。 –

+0

這是friggin太棒了!謝謝! –

0

您的查詢看起來不錯,不知道爲什麼它不工作。

嘗試使用ORDER BY UUID()。我的情況下,它每次生成1行(非空)。

+0

我需要爲每個公司隨機抽一個贊助商。這就是爲什麼我使用RAND()。使用ORDER BY 1或ORDER BY ID將始終拉第一條記錄。我如何獲得一個隨機贊助商。 –

+0

我的壞...誤解了這個問題。我現在編輯了我的答案。請檢查。 – shailesh88

+0

我嘗試了ORDER BY UUID(),我仍然只是第一個贊助商。 –