繁体   English   中英

MySQL使用UNION或OUTER LEFT JOIN

[英]MySQL Using UNION or OUTER LEFT JOIN

我一直在努力寻找一个足够简单的查询。 我有三个表,客户,联系人和活动。 每次记录活动时,它都会记录AccountID,Contact Subject,TimeDate。

我查询“活动”表以显示上一个星期每个AccountID的所有活动计数。

我用:

select
accounts.account as Account,
count(distinct activities.contactid) as Users,
from accounts, activities
where activities.accountid=accounts.accountid
AND completeddate >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND completeddate < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
group by accounts.account asc;

结果是这样的:

Account      Users
ACME Ltd     4
Warner Bros  6
RBS          9

等等..

活动表有2千万行数据,运行时间约20秒。

但是,我想要一个完整的列表。 我想将结果与该月没有任何活动的AccountID的列表合并。

Account      Users
ACME Ltd     4
Warner Bros  6
RBS          9
Microsoft    0  or NULL

等等...

我已经尝试过像这样的UNION:

select Account, '' from Accounts
UNION
select
accounts.account as Account,
count(distinct activities.contactid) as Users
from accounts, activities
where activities.accountid=accounts.accountid
AND completeddate >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND completeddate < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
group by accounts.account asc;

根据我对UNION的了解,它应该返回唯一列表(无重复项)。 但是当我只有大约900个帐户时,我得到的是aprox 1400帐户列表。

我已经尝试过LEFT OUTER JOIN,但这似乎永远存在(我在2小时后将其杀死)

有人对我可以尝试的内容有任何建议吗?

谢谢

这是您尝试过的left outer join联接吗?

select accounts.account as Account,
       count(distinct activities.contactid) as Users
from accounts left outer join
     activities
     on activities.accountid=accounts.accountid
where completeddate >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY and
      completeddate < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
group by accounts.account asc;

这应该具有与原始查询相同的性能。

顺便说一句,您应该始终使用显式join语法( from子句中的join关键字),而不是where子句中的隐式联接。

似乎completeddate在活动表中(始终使用别名)。 在这种情况下,需要将其移到on子句中:

select accounts.account as Account,
       count(distinct activities.contactid) as Users
from accounts left outer join
     activities
     on activities.accountid=accounts.accountid and
        activities.completeddate >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY and
        activities.completeddate < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
group by accounts.account asc;

这取决于您是否要将selects与“ or”或“ and”-逻辑结合在一起。

对于“或”,请使用UNION DISTINCT ,对于“或”,请在主键上使用INNER JOIN

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM