Table 1:
| user | bid |
---------------------------
| may | 0.06 |
| dee | 0.05 |
| jay | 0.04 |
| mac | 0.03 |
| dee | 0.02 |
| mac | 0.01 |
Table 2:
| user | ratio|
---------------------------
| dee | .25 |
| jay | .45 |
| mac | .85 |
| fil | .75 |
| may | .95 |
I want to count how many distinct users from table 1 fall within certain ranges (0-.99) based on their ration in table 2.
Output:
| Ratio_Group | Count|
---------------------------
| 0.00-0.25 | 1 |
| 0.25-0.50 | 1 |
| 0.50-0.75 | 0 |
| 0.75-0.99 | 2 |
Is there 1 query per ratio grouping I can use to count the distinct users in table 1 based on what grouping they fall into in table 2? I was using a combination of a IF and COUNT statement, but each row in table 1 was evaluated and counted instead of just the DISTINCT users and therefore I got an inflated result.
Ex:
COUNT((IF table1.user <0.25,1,0))
COUNT((IF table1.user BETWEEN 0.25 AND 0.50,1,0))
etc...
Each of the 4 queries will be used in a stored proc so I need 1 query per ratio grouping so I may assign the result of each group to a variable in the stored proc.
You can use SUM
with a combination of BETWEEN
and DISTINCT
SELECT
SUM(DISTINCT `table2`.`ratio` BETWEEN 0.00 AND 0.25) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user) GROUP BY table1.user
SELECT
SUM(DISTINCT `table2`.`ratio` BETWEEN 0.25 AND 0.50) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user) GROUP BY table1.user
SELECT
SUM(DISTINCT `table2`.`ratio` BETWEEN 0.50 AND 0.75 ) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user) GROUP BY table1.user
SELECT
SUM(DISTINCT `table2`.`ratio` BETWEEN 0.75 AND 0.99) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user) GROUP BY table1.user
Or you can just combine them one as
SELECT '0.00 - 0.25' Ratio_Group ,
SUM(DISTINCT `table2`.`ratio` BETWEEN 0.00 AND 0.25) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user) GROUP BY table1.user
UNION ALL
SELECT '0.25 - 0.50' Ratio_Group ,
SUM(DISTINCT `table2`.`ratio` BETWEEN 0.25 AND 0.50) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user) GROUP BY table1.user
UNION ALL
SELECT '0.50 - 0.75' Ratio_Group ,
SUM(DISTINCT `table2`.`ratio` BETWEEN 0.50 AND 0.75 ) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user) GROUP BY table1.user
UNION ALL
SELECT '0.75 - 0.99' Ratio_Group ,
SUM(DISTINCT `table2`.`ratio` BETWEEN 0.75 AND 0.99) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user) GROUP BY table1.user
EDIT Below query will count the distinct users for each ratio group
SELECT '0.00 - 0.25' Ratio_Group ,
COUNT(DISTINCT `table2`.`user` ) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user)
WHERE `table2`.`ratio` BETWEEN 0.00 AND 0.25
UNION ALL
SELECT '0.25 - 0.50' Ratio_Group ,
COUNT(DISTINCT `table2`.`user`) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user)
WHERE `table2`.`ratio` BETWEEN 0.25 AND 0.50
UNION ALL
SELECT '0.50 - 0.75' Ratio_Group ,
COUNT(DISTINCT `table2`.`user` ) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user)
WHERE `table2`.`ratio` BETWEEN 0.50 AND 0.75
UNION ALL
SELECT '0.75 - 0.99' Ratio_Group ,
COUNT(DISTINCT `table2`.`user`) `count`
FROM table1 JOIN table2 ON (table1.user =table2.user)
WHERE `table2`.`ratio` BETWEEN 0.75 AND 0.99
If you don't mind only grabbing the groups that have members, you can do something like this. It uses an inner query to grab unique members and their corresponding ratios, then uses a containing table to group them into ratio groups by those ratios. The nice thing is you don't hard code row groups, which isn't very SQL-like; the downside is you don't see row "members" that have a count of 0.
SELECT
CONCAT(
((CEIL(ratio * 4) * 0.25 ) - 0.25),
" - ",
(CEIL( ratio *4 ) * 0.25)
) AS ratio_group,
COUNT(user) AS user_count
FROM (
SELECT
t1.user,
t2.ratio
FROM
`table1` t1
INNER JOIN
`table2` t2 ON t2.user = t1.user
GROUP BY
t1.user
) virtual_table
GROUP BY
CEIL(ratio * 4)
Per your additional comments, you can combine all the data into a string, and assign to a variable like so. This is a hell of a bastardization. What you do with that data (it's essentially a CSV string at that point) is up to YOU, haha.
@data =
(SELECT
GROUP_CONCAT(combined SEPARATOR ';')
FROM (
SELECT
CONCAT(
'"',
CONCAT(
((CEIL(ratio * 4) * 0.25) - 0.25),
" - ",
(CEIL( ratio *4 ) * 0.25)
),
'",',
COUNT( user )
) AS combined
FROM (
SELECT
t1.user,
t2.ratio
FROM
`table1` t1
INNER JOIN
`table2` t2 ON t2.user = t1.user
GROUP BY
t1.user
) virtual_table
GROUP BY
CEIL( ratio *4 )
) virtual_table2 )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.