dark_destroyer Posted May 10, 2013 Share Posted May 10, 2013 Hi All, I have been struggling with what seems a simple enough query. I have three tables, Accounts, Contacts & Activities. Everytime an Activity is logged it logs the AccountID, Contact Subject, TimeDate. I query the Activities table to show me all the activity count from the previous week for each AccountID. I use: 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; The result is something like This: Account Users ACME Ltd 4 Warner Bros 6 RBS 9 etc.. The activities table has baout 20 million rows and this runs in about 20 seconds. However, I want a comprehensive list. I want to combine the results with a list of AccountID's that havent had any activity for that month. Account Users ACME Ltd 4 Warner Bros 6 RBS 9 Microsoft 0 or NULL etc... i have tried to UNION like this: 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; From what i understand about UNION is that it should return a unique list (without duplicates). But what i get is a list of aprox 1400 accounts with when I only have approx 900 Accounts. I have tried LEFT OUTER JOIN but this just seemed to run forever ( i killed it after 2 hours) Does anyone have any suggestions on what I can try? Thanks Dark Quote Link to comment https://forums.phpfreaks.com/topic/277882-using-union-or-left-outer-join/ Share on other sites More sharing options...
taquitosensei Posted May 10, 2013 Share Posted May 10, 2013 (edited) As far as I know UNION removes duplicate rows, so the count(distinct contactid) in the second part would make it not a distinct row. So in your query you're getting everything, then everything with activity in the last week. Hi All, I have been struggling with what seems a simple enough query. I have three tables, Accounts, Contacts & Activities. Everytime an Activity is logged it logs the AccountID, Contact Subject, TimeDate. I query the Activities table to show me all the activity count from the previous week for each AccountID. I use: 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; The result is something like This: Account Users ACME Ltd 4 Warner Bros 6 RBS 9 etc.. The activities table has baout 20 million rows and this runs in about 20 seconds. However, I want a comprehensive list. I want to combine the results with a list of AccountID's that havent had any activity for that month. Account Users ACME Ltd 4 Warner Bros 6 RBS 9 Microsoft 0 or NULL etc... i have tried to UNION like this: 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; From what i understand about UNION is that it should return a unique list (without duplicates). But what i get is a list of aprox 1400 accounts with when I only have approx 900 Accounts. I have tried LEFT OUTER JOIN but this just seemed to run forever ( i killed it after 2 hours) Does anyone have any suggestions on what I can try? Thanks Dark Edited May 10, 2013 by taquitosensei Quote Link to comment https://forums.phpfreaks.com/topic/277882-using-union-or-left-outer-join/#findComment-1429533 Share on other sites More sharing options...
dark_destroyer Posted May 10, 2013 Author Share Posted May 10, 2013 Hi, Thanks for the reply, but the count distinct is only counting distinct contactid's not accountid's so it shouldnt affect the query? Quote Link to comment https://forums.phpfreaks.com/topic/277882-using-union-or-left-outer-join/#findComment-1429536 Share on other sites More sharing options...
mikosiko Posted May 10, 2013 Share Posted May 10, 2013 2 questions: - what is the result of this sentence when you run it in your mysql client (phpmyadmin maybe?)... post back the results. EXPLAIN SELECT accounts.account as Account, count(distinct activities.contactid) as Users FROM accounts LEFT 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; - which are the defined Indexes for your tables accounts and activities Quote Link to comment https://forums.phpfreaks.com/topic/277882-using-union-or-left-outer-join/#findComment-1429539 Share on other sites More sharing options...
taquitosensei Posted May 10, 2013 Share Posted May 10, 2013 Hi, Thanks for the reply, but the count distinct is only counting distinct contactid's not accountid's so it shouldnt affect the query? It does effect the query. Because in first query the value you're getting is '' The second query you're getting a number. Quote Link to comment https://forums.phpfreaks.com/topic/277882-using-union-or-left-outer-join/#findComment-1429544 Share on other sites More sharing options...
Barand Posted May 10, 2013 Share Posted May 10, 2013 (edited) Try SELECT accounts.account as Account, COUNT(distinct activities.contactid) as Users, from accounts LEFT JOIN activities ON activities.accountid=accounts.accountid AND completeddate >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY AND completeddate < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY GROUP BY accounts.account ps INDEX completeddate if you haven't already Edited May 10, 2013 by Barand Quote Link to comment https://forums.phpfreaks.com/topic/277882-using-union-or-left-outer-join/#findComment-1429549 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.