Go Back   CodingForums.com > :: Server side development > MySQL

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 01-11-2013, 08:44 PM   PM User | #1
weaksauce
New Coder

 
Join Date: Nov 2007
Posts: 34
Thanks: 9
Thanked 0 Times in 0 Posts
weaksauce is an unknown quantity at this point
single table left join?

I have a single table that I feel is giving me more problems than it should. I want to select a set of users and a set of organizations that I want to check and return a count that also includes null values.

only_table :
Code:
user_id     org_id
123          ABC
456          AAA
789          DEF
123          ABC
789          GHI
456          BBB
907          DEF
878          ABC
I would want to select only Users: 123,456,789 and Orgs: ABC,DEF,GHI

Example Return:
Code:
user_id     count
123          2
456          0
789          2
The only solutions I could come up with was creating a temporary table...
Code:
CREATE TEMPORARY TABLE `temp1` AS (
	SELECT `user_id` AS `user`,COUNT(*) AS `num` FROM `only_table`
	WHERE `org_id`
	IN (
	 'ABC','DEF','GHI'
	)
	GROUP BY `user_id`
);
CREATE TEMPORARY TABLE `temp2` AS (
	SELECT DISTINCT(`user_id`) AS `user` FROM `only_table`
		WHERE `user_id` 
		IN (
				'123','456','789'
		)
);
SELECT 
	`temp2`.`user`,
	`temp1`.`num`
FROM `temp2` 
LEFT JOIN `temp1` ON
	`temp1`.`user` = `temp2`.`user`
GROUP BY `temp2`.`user`;
or being unable to get the null values.
Code:
SELECT `user_id`,COUNT(`user_id`) FROM (
	SELECT 
		`only_table`.`user_id`
	FROM `only_table`
	WHERE 
		`only_table`.`user_id` IN (
			'123',
			'456',
			'789'
		) AND `only_table`.`org_id` IN (
			'ABC',
			'DEF',
			'GHI'
		)
) as `temp`
GROUP BY `user_id`
I am being dumb right now or is there some way to retrieve null values without a left join or using some type of temporary table,view,procedure?

Any help will be appreciated, thanks in advance!
__________________
Time after Time

Last edited by weaksauce; 01-12-2013 at 12:12 AM..
weaksauce is offline   Reply With Quote
Old 01-11-2013, 09:22 PM   PM User | #2
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,247
Thanks: 59
Thanked 3,998 Times in 3,967 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
HUH???

I *assume* you mean you want to include NULL values for the user_ids, only?
It would make no sense to accept NULLs for the org_id if you want to get the counts *BY* org_id.

So what's wrong with simply
Code:
SELECT org_id, COUNT(*) as howMany
FROM only_table
WHERE (user_id IS NULL OR user_id IN (123,456,789) )
AND org_id IN ('ABC','DEF','GHI') 
GROUP BY org_id
If your user_id values are always 0 or greater, another sneaky trick would be:
Code:
SELECT org_id, COUNT(*) as howMany
FROM only_table
WHERE  IFNULL(user_id,-1) IN (-1,123,456,789) 
AND org_id IN ('ABC','DEF','GHI') 
GROUP BY org_id
Would have been helpful if you'd shown an example that included NULL values and then the expected results therefrom.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 01-11-2013, 09:24 PM   PM User | #3
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,247
Thanks: 59
Thanked 3,998 Times in 3,967 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
In other words, if you had shown us
Code:
user_id     org_id
123          ABC
456          AAA
789          DEF
123          ABC
789          GHI
456          BBB
907          DEF
878          ABC
456          [null]
with results of
Code:
user_id     count
123          2
456          1
789          2
then I'd know I was right.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 01-11-2013, 09:53 PM   PM User | #4
weaksauce
New Coder

 
Join Date: Nov 2007
Posts: 34
Thanks: 9
Thanked 0 Times in 0 Posts
weaksauce is an unknown quantity at this point
user_id and org_id are never null (nor unique), what I'm trying to do is basically take a table and:

select a list of users that are members of a list of orgs and count how many times they are in those specific organizations, there also are other users and orgs outside of my query that I don't care about

Specifically I'm running 64 users and 32 organizations but only 44 users show up because the other 20 don't belong to any of the organizations I'm checking for, I would like the other 20 to show up with a 0 beside them or null for that matter.

Edit: Both solutions above work, just the second sub-query doesn't give null values. I just didn't know to get the null values without using a temporary table.
__________________
Time after Time

Last edited by weaksauce; 01-11-2013 at 10:03 PM..
weaksauce is offline   Reply With Quote
Old 01-11-2013, 10:24 PM   PM User | #5
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,247
Thanks: 59
Thanked 3,998 Times in 3,967 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
OH!!!

COMPLETELY different that what I thought!


Yes, LEFT JOIN.

Code:
SELECT D.user_id,  COUNT(T.org_id) AS howMany
FROM ( SELECT DISTINCT user_id FROM only_table ) AS D
LEFT JOIN only_table AS T
     ON ( 
          D.user_id = T.user_id 
          AND T.org_id IN ( 'ABC','DEF','GHI' )
     )
GROUP BY D.user_id
ORDER BY D.user_id
("D" for "Derived", "T" for "Table")

Note that the T.org_id restriction *MUST* be part of the ON condition. It can *NOT* be moved to the WHERE.

The COUNT(T.org_id) can of course be COUNT(T.user_id) instead. Makes no difference.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.

Last edited by Old Pedant; 01-11-2013 at 10:32 PM..
Old Pedant is offline   Reply With Quote
Users who have thanked Old Pedant for this post:
weaksauce (01-11-2013)
Old 01-11-2013, 11:05 PM   PM User | #6
weaksauce
New Coder

 
Join Date: Nov 2007
Posts: 34
Thanks: 9
Thanked 0 Times in 0 Posts
weaksauce is an unknown quantity at this point
That worked... You're awesome!

I had to do a sub-query to only return the specific user list, I think I could have added it to the JOIN but it would have taken longer right?

Code:
SELECT * FROM (
	SELECT D.user_id,  COUNT(T.org_id) AS howMany
	FROM ( SELECT DISTINCT user_id FROM only_table ) AS D
	LEFT JOIN only_table AS T
		 ON ( 
			  D.user_id = T.user_id 
			  AND T.org_id IN ('ORG1','ORG2'...)
		)
	GROUP BY D.user_id
	ORDER BY D.user_id
	) AS X
WHERE
X.user_id IN ('USER1','USER2'...)
__________________
Time after Time
weaksauce is offline   Reply With Quote
Old 01-11-2013, 11:57 PM   PM User | #7
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,247
Thanks: 59
Thanked 3,998 Times in 3,967 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
??? I thought you wanted *ALL* users? You wrote
Quote:
I'm running 64 users and 32 organizations but only 44 users show up because the other 20 don't belong to any of the organizations I'm checking for, I would like the other 20 to show up with a 0 beside them
I don't see anything in that statement that says you need to limit the users.

So why do you need the
Code:
WHERE X.user_id IN ('USER1','USER2'...)
????

But if you do need it, then there's an easier way:
Code:
SELECT D.user_id,  COUNT(T.org_id) AS howMany
FROM ( 
    SELECT DISTINCT user_id FROM only_table
    WHERE user_id IN ('USER1','USER2',...)
    ) AS D
LEFT JOIN only_table AS T
     ON ( 
          D.user_id = T.user_id 
          AND T.org_id IN ( 'ABC','DEF','GHI' )
     )
GROUP BY D.user_id
ORDER BY D.user_id
Why get and count them only to throw them away *after* the count? Just eliminate the unwanted users before the join and count ever take place.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 01-12-2013, 12:10 AM   PM User | #8
weaksauce
New Coder

 
Join Date: Nov 2007
Posts: 34
Thanks: 9
Thanked 0 Times in 0 Posts
weaksauce is an unknown quantity at this point
Perfect. Thanks!
__________________
Time after Time
weaksauce is offline   Reply With Quote
Reply

Bookmarks

Tags
join, left, mysql, select, single

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 06:25 AM.


Advertisement
Log in to turn off these ads.