MySQL使用UNION或OUTER LEFT JOIN
我一直在努力寻找似乎足够简单的查询。 我有三个表,帐户,联系人&活动。 每次记录活动时,它都会记录AccountID,Contact Subject,TimeDate。MySQL使用UNION或OUTER LEFT JOIN
我查询“活动”表以显示每个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
等。
活动表已baout 2000万行,这个运行在约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;
从我了解关于联盟的是,它应该返回一个独特的名单(不重复)。但是,当我只有约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;
这取决于你是否希望将选择与“或”或“和”结合 - 逻辑。
对于“或”使用UNION DISTINCT
表示“和”在主键上使用INNER JOIN
。
我试过UNION DISTINCT,但由于某种原因,当我只有900个账户时,它给了我1495行。这是什么令我困惑。谢谢 – user2054962 2013-05-10 15:01:35
如果您只选择帐户ID,它将起作用,否则它会认为结果不同,因为其他列是不同的。 – Adder 2013-05-10 15:13:26
但后来我放弃了“计数”这是查询的总体目标。 – user2054962 2013-05-10 15:16:44
谢谢戈登,这就是我的尝试,但它只是给了我相同的结果:选择 accounts.account帐户, 计数(不同的活动。的ContactID),为用户从 帐户,活动 其中activities.accountid = accounts.accountid AND completeddate> = CURDATE() - INTERVAL DAYOFWEEK(CURDATE())+ 6 DAY AND completeddate
user2054962
2013-05-10 14:58:16
@ user2054962。 。 。您应该始终为您的列使用别名。 “completeddate”列在'activities'表(推测是)中,并且将'left outer join'转换为'inner join'。解决方案是将逻辑移入“on”子句。 – 2013-05-10 15:01:28
谢谢戈登,现在只是测试它,我甚至不知道你冷用它那样!会让你知道它是怎么回事,谢谢。 – user2054962 2013-05-10 15:10:21