[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

constructing a query with group by

Posted on 2007-11-20
13
Medium Priority
?
230 Views
Last Modified: 2010-08-05
I'm having problems constructing a query that returns the desired results.

I'm working with PHPBB2 incidentally.

$sql = 'SELECT
 u.user_id,
 u.username,
 count(u.user_id) as post_count
FROM
 '.USERS_TABLE.' as u,
 '.POSTS_TABLE.' as p
WHERE
 u.user_id = p.poster_id AND
 p.post_time > '.(time()-(7*24*3600)).' AND
 u.user_id <> '.ANONYMOUS.'
GROUP BY
 u.user_id, u.username
ORDER BY
 post_count DESC';

$sql = 'SELECT
 u.user_id,
 u.username,
 count(u.user_id) as topic_count
FROM
 '.USERS_TABLE.' as u,
 '.TOPICS_TABLE.' as t
WHERE
 u.user_id = t.topic_poster AND
 t.topic_time > '.(time()-(7*24*3600)).' AND
 u.user_id <> '.ANONYMOUS.'
GROUP BY
 u.user_id, u.username
ORDER BY
 topic_count DESC';

I'm basically trying to combine the above two queries. I can get them to work individually, but fail when I try to combine them.

It's should be fairly self explanatory, but I'm trying to select the post and topic counts for users in the past week, ultimately to be ordered by 'post_count DESC, topic_count DESC'. i.e. username | # of posts made | # of topics created

Could someone kindly shed some light as to how I'd go about doing this...
0
Comment
Question by:calcanus
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 4
13 Comments
 
LVL 17

Expert Comment

by:HuyBD
ID: 20324992
try this


$sql = '(SELECT
 u.user_id,
 u.username,
 count(u.user_id) as post_count
FROM
 '.USERS_TABLE.' as u,
 '.POSTS_TABLE.' as p
WHERE
 u.user_id = p.poster_id AND
 p.post_time > '.(time()-(7*24*3600)).' AND
 u.user_id <> '.ANONYMOUS.'
GROUP BY
 u.user_id, u.username
ORDER BY
 post_count DESC)';
$sql.=' UNION ALL '
$sql.='(SELECT
 u.user_id,
 u.username,
 count(u.user_id) as topic_count
FROM
 '.USERS_TABLE.' as u,
 '.TOPICS_TABLE.' as t
WHERE
 u.user_id = t.topic_poster AND
 t.topic_time > '.(time()-(7*24*3600)).' AND
 u.user_id <> '.ANONYMOUS.'
GROUP BY
 u.user_id, u.username
ORDER BY
 topic_count DESC)';

Open in new window

0
 
LVL 25

Expert Comment

by:imitchie
ID: 20325406
hope this satisfies your requirement
$sql = 'SELECT
 u.user_id,
 u.username,
 count(u.user_id) as post_count,
 count(u.user_id) as topic_count
FROM
 '.USERS_TABLE.' as u
 LEFT JOIN '.POSTS_TABLE.' as p ON u.user_id = p.poster_id AND
   p.post_time > '.(time()-(7*24*3600)).'
 LEFT JOIN '.TOPICS_TABLE.' as t ON u.user_id = t.topic_poster AND
   t.topic_time > '.(time()-(7*24*3600)).'
WHERE
 u.user_id <> '.ANONYMOUS.'
GROUP BY
 u.user_id, u.username
ORDER BY
 post_count DESC, topic_count DESC';

Open in new window

0
 

Author Comment

by:calcanus
ID: 20327916
HuyBD,

That works but both results; post_count and topic_count are returned separately:

user_id  |  username  |  post_count
2  |  user1 |  9
3  |  user2  |  2
4  |  user3  |  3
2  |  user1  |  5
3  |  user2  |  1
4  |  user3  |  1

Is there anyway to get the results as follows:

user_id  |  username  |  post_count | topic_count
2  |  user1 |  9  | 5
3  |  user2  |  2 | 1
4  |  user3  |  3 | 1

?

@imitchie: The wrong results are returned with that query I'm afraid, which is the exact problem I encountered with everything I tried.

user_id | username | post_count | topic_count
2 | user1 | 45 | 45
4 | user3  | 3 | 3
3 | user2  | 2 | 2
0
Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf

 
LVL 17

Expert Comment

by:HuyBD
ID: 20327992
you may try

HuyBD
$sql = '(SELECT
 u.user_id,
 u.username,
 count(u.user_id) as post_count
FROM
 '.USERS_TABLE.' as u,
 '.POSTS_TABLE.' as p
WHERE
 u.user_id = p.poster_id AND
 p.post_time > '.(time()-(7*24*3600)).' AND
 u.user_id <> '.ANONYMOUS.'
GROUP BY
 u.user_id, u.username
ORDER BY
 post_count DESC)';
$sql.=' UNION '
$sql.='(SELECT
 u.user_id,
 u.username,
 count(u.user_id) as topic_count
FROM
 '.USERS_TABLE.' as u,
 '.TOPICS_TABLE.' as t
WHERE
 u.user_id = t.topic_poster AND
 t.topic_time > '.(time()-(7*24*3600)).' AND
 u.user_id <> '.ANONYMOUS.'
GROUP BY
 u.user_id, u.username
ORDER BY
 topic_count DESC)';

Open in new window

0
 
LVL 17

Expert Comment

by:HuyBD
ID: 20328009
or
$sql = 'SELECT * FROM (SELECT
 u.user_id,
 u.username,
 count(u.user_id) as column_count
FROM
 '.USERS_TABLE.' as u,
 '.POSTS_TABLE.' as p
WHERE
 u.user_id = p.poster_id AND
 p.post_time > '.(time()-(7*24*3600)).' AND
 u.user_id <> '.ANONYMOUS.'
GROUP BY
 u.user_id, u.username)';
$sql.=' UNION ALL '
$sql.='(SELECT
 u.user_id,
 u.username,
 count(u.user_id) as column_count
FROM
 '.USERS_TABLE.' as u,
 '.TOPICS_TABLE.' as t
WHERE
 u.user_id = t.topic_poster AND
 t.topic_time > '.(time()-(7*24*3600)).' AND
 u.user_id <> '.ANONYMOUS.'
GROUP BY
 u.user_id, u.username) as T
ORDER BY
 column_count DESC'; 

Open in new window

0
 
LVL 17

Expert Comment

by:HuyBD
ID: 20328093
sorry, I have missing!
$sql = 'SELECT user_id,username,count(post_count) as post_count,
count(topic_count) as topic_count FROM (SELECT
 u.user_id,
 u.username,
 count(u.user_id) as post_count,
 0 as topic_count
FROM
 '.USERS_TABLE.' as u,
 '.POSTS_TABLE.' as p
WHERE
 u.user_id = p.poster_id AND
 p.post_time > '.(time()-(7*24*3600)).' AND
 u.user_id <> '.ANONYMOUS.')';
$sql.=' UNION ALL '
$sql.='(SELECT
 u.user_id,
 u.username,
 0 as post_count,
 count(u.user_id) as topic_count
FROM
 '.USERS_TABLE.' as u,
 '.TOPICS_TABLE.' as t
WHERE
 u.user_id = t.topic_poster AND
 t.topic_time > '.(time()-(7*24*3600)).' AND
 u.user_id <> '.ANONYMOUS.') as T
GROUP BY
user_id, username
ORDER BY
 column_count DESC'; 

Open in new window

0
 
LVL 25

Expert Comment

by:imitchie
ID: 20330723
sorry, was counting the user_id. just replace with counting something from the post and topics tables, as follows
$sql = 'SELECT
 u.user_id,
 u.username,
 count(p.poster_id) as post_count,
 count(t.topic_poster) as topic_count
FROM
 '.USERS_TABLE.' as u
 LEFT JOIN '.POSTS_TABLE.' as p ON u.user_id = p.poster_id AND
   p.post_time > '.(time()-(7*24*3600)).'
 LEFT JOIN '.TOPICS_TABLE.' as t ON u.user_id = t.topic_poster AND
   t.topic_time > '.(time()-(7*24*3600)).'
WHERE
 u.user_id <> '.ANONYMOUS.'
GROUP BY
 u.user_id, u.username
ORDER BY
 post_count DESC, topic_count DESC';

Open in new window

0
 

Author Comment

by:calcanus
ID: 20331562
@imitchie: That still returns the same results.

 It's seems as though the post count is getting multiplied by the topic count.

2 | user1 | 45 | 45
4 | user3  | 3 | 3
3 | user2  | 2 | 2

This is what it should be:

2  |  user1 |  9  | 5
3  |  user2  |  2 | 1
4  |  user3  |  3 | 1

@HuyBD:

There's a query in there some where. I can't figure out where, that query is a little beyond my ability.
0
 

Author Comment

by:calcanus
ID: 20331577
Sorry, I mean an error.
0
 
LVL 25

Expert Comment

by:imitchie
ID: 20332053
i see the error of my ways leading you up the rosy garden path. please try this
 count(distinct p.poster_id) as post_count,
 count(distinct t.topic_poster) as topic_count

Open in new window

0
 

Author Comment

by:calcanus
ID: 20332359
The results remain incorrect I'm afraid.

2  |  user1 | 1 | 1
3  |  user2  | 1 | 1
4  |  user3  | 1 | 1

All post and topic counts return as 1.
0
 
LVL 25

Accepted Solution

by:
imitchie earned 1000 total points
ID: 20332373
okay, assuming posts by the same user will always have distinct post_time, and topic_time will always be distinct...

 count(distinct p.post_time) as post_count,
 count(distinct t.topic_time) as topic_count

will now do it. just in case, I'm getting phpbb2 resurrected on my test server in case i need to actually test my next suggestion
0
 

Author Comment

by:calcanus
ID: 20334068
ah ha! The query now returns the correct result.

I was a bit worried about the possibility of two topics or posts being posted at exactly the same time, so I substituted p.post_time and t.topic_time for p.post_id and  t.topic_id , i.e.

count(DISTINCT p.post_id) AS post_count,
count(DISTINCT t.topic_id) AS topic_count

and the results remain correct.

Thanks for your help!
0

Featured Post

Moving data to the cloud? Find out if you’re ready

Before moving to the cloud, it is important to carefully define your db needs, plan for the migration & understand prod. environment. This wp explains how to define what you need from a cloud provider, plan for the migration & what putting a cloud solution into practice entails.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this blog post, we’ll look at how ClickHouse performs in a general analytical workload using the star schema benchmark test.
In this blog post, we’ll look at how using thread_statistics can cause high memory usage.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question