0

私は、十分に単純なクエリと思われるものに苦労してきました。アカウント、連絡先、アクティビティの 3 つのテーブルがあります。アクティビティが記録されるたびに、AccountID、Contact Subject、TimeDate が記録されます。

各 AccountID の前週のすべてのアクティビティ数を表示するために、Activities テーブルにクエリを実行します。

私が使う:

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,000 万行あり、これは約 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 個のアカウントしかないのに、約 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内のキーワード) を使用する必要があります。fromwhere

アクティビティ テーブルにあるようです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 に答える