2017-02-12 85 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(),我仍然只是第一个赞助商。 –