如何让SELECT“知道”哪个实体有更多的元素?

时间:2014-07-01 10:23:40

标签: mysql sql database select

我有一个简单的数据库,它有三个表(companyphoneemail),这些表通过规则相关:

  • 公司可能有零个或多个电话号码;
  • 公司可能有零个或多个电子邮件地址。

这是MySQL代码:Pastebin


让我们假设以下两种情况:

  • 一家公司有3部电话和2封电子邮件(案例1
  • 一家公司有2部电话和3封电子邮件(案例2

我想创建一个返回以下内容的SELECT:

案例1

Company         Phone       E-mail
--------------------------------------------
Test Company    1111222     export@testco.co
Test Company    2222222     import@testco.co
Test Company    3333222 
--------------------------------------------

案例2

Company         Phone       E-mail
--------------------------------------------
Test Company    1111222     export@testco.co
Test Company    2222222     import@testco.co
Test Company                sales@testco.co
--------------------------------------------

SELECT应该"知道",对于给定的公司,哪个实体有更多元素(phoneemail),然后返回一个结果,其中的数量为rows等于具有更多元素的实体中的元素数(案例1中为phone;案例2中为email

我无法弄清楚如何做到这一点。这是我能做的最好的事:Pastebin

1 个答案:

答案 0 :(得分:3)

这在MySQL中很难,但它是可能的。这是逻辑。枚举每个公司的电子邮件和电话的值。然后根据公司和序列号汇总这些:

select ep.company, min(ep.email) as email, min(ep.phone) as phone
from ((select e.company, e.email, NULL as phone,
              (@rne := if(@company = company, @rne + 1, if(@company := company, 1, 1)) ) as seqnum
       from email e cross join
            (select @rne := 0, @company := '') vars
       order by e.company
      ) union all
      (select p.company, NULL, p.phone,
              (@rnp := if(@companyp = company, @rnp + 1, if(@companyp := company, 1, 1)) ) as seqnum
       from phone p cross join
            (select @rnp := 0, @companyp := '') vars
       order by p.company
      )
     ) ep
group by ep.company, ep.seqnum
order b ep.company, ep.seqnum;

表达式:

 (@rne := if(@company = company, @rne + 1, if(@company := company, 1, 1)) ) as seqnum

用于设置seqnum是一种在MySQL中安全使用变量的方法。请注意,MySQL不保证select中表达式的评估顺序,所以更自然:

 @rne := if(@company = company, @rne + 1, 1), @company := company

可能不起作用,因为第二个将首先评估。嵌套赋值的这种方法没有这个问题。