0

我一直在努力解决看似简单的查询。我有三个表,帐户、联系人和活动。每次记录活动时,它都会记录 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

ETC..

活动表有 2000 万行,运行时间约为 20 秒。

但是,我想要一份完整的清单。我想将结果与该月没有任何活动的 AccountID 列表结合起来。

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

ETC...

我试过这样联合:

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 个帐户时,我得到的是大约 1400 个帐户的列表。

我试过 LEFT OUTER JOIN 但这似乎永远运行(我在 2 小时后杀死了它)

有人对我可以尝试什么有任何建议吗?

谢谢

4

2 回答 2

1

这是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语法(子句join中的关键字from),而不是子句中的隐式连接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;
于 2013-05-10T14:46:25.890 回答
0

这取决于您是否要将选择与“或”或“和” - 逻辑结合起来。

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

于 2013-05-10T14:46:48.870 回答