I've inherited a CodeIgniter query that generates this SQL
EXAMPLE:
SELECT `users`.`id`, `users`.`username`, `users`.`email`, `users`.`photo`, `users`.`rating`
FROM `pool_details`
JOIN `users` ON `users`.`id` = `pool_details`.`captain_id`
WHERE `pool_details`.`pool_type` =0
AND `pool_details`.`pool_close` > '2020-01-02 18:39:42'
GROUP BY `pool_details`.`captain_id`
ORDER BY `pool_details`.`members_count` DESC
LIMIT 20
ERROR - 2020-01-02 18:39:42 --> Query error: Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'pool_details.members_count' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by - Invalid query:
Here is the same data with some "extra columns" and the offending clauses removed:
SELECT users.id, users.username, users.email,users.rating,pool_details.members_count,pool_details.pool_type,pool_details.pool_close
FROM pool_details
JOIN users ON users.id = pool_details.captain_id
WHERE pool_details.pool_type = 0 AND pool_details.pool_close > '2020-01-02 18:39:42'
ORDER BY pool_details.members_count DESC;
//GROUP BY `pool_details`.`captain_id`
+----+----------+--------------------------+--------+---------------+-----------+---------------------+
| id | username | email | rating | members_count | pool_type | pool_close |
+----+----------+--------------------------+--------+---------------+-----------+---------------------+
| 13 | Ronaldo | [email protected] | 4.6 | 100 | 0 | 2020-01-04 03:00:00 |
| 13 | Ronaldo | [email protected] | 4.6 | 100 | 0 | 2020-01-03 23:30:00 |
| 13 | Ronaldo | [email protected] | 4.6 | 100 | 0
...
| 13 | Ronaldo | [email protected] | 4.6 | 0 | 0 | 2020-01-03 00:00:00 |
| 13 | Ronaldo | [email protected] | 4.6 | 0 | 0 | 2020-01-03 00:30:00 |
| 13 | Ronaldo | [email protected] | 4.6 | 0 | 0 | 2020-01-04 21:30:00 |
| 13 | Ronaldo | [email protected] | 4.6 | 0 | 0 | 2020-01-03 03:00:00 |
+----+----------+--------------------------+--------+---------------+-----------+---------------------+
28 rows in set (0.00 sec)
What I want is to:
- Show User's username, email and rating
- Order by "members_count"
- Show the user only once
For example:
SELECT DISTINCT users.id, users.username, users.email,users.rating
FROM pool_details
JOIN users ON users.id = pool_details.captain_id
WHERE pool_details.pool_type = 0 AND pool_details.pool_close > '2020-01-02 18:39:42';
+----+----------+--------------------------+--------+
| id | username | email | rating |
+----+----------+--------------------------+--------+
| 5 | wheel | [email protected] | NULL |
| 13 | Ronaldo | [email protected] | 4.6 |
+----+----------+--------------------------+--------+
2 rows in set (0.00 sec)
<= This shows the users individually ... but it's *NOT* ordered by "members_count".
Q: Is there any combination of "GROUP BY" and/or "DISTINCT" that I can use with mySql 5.7 that will give me the result set I need?
members_count
is functionally dependent (i.e. we know the value ofmembers_count
column from all rows in a collapsed group are the same), then we could just wrap in an aggregate function. .e.gORDER BY MAX(pool_details.members_count) DESC
. (we could use MIN() in place of MAX(), result will be the same, if we are guaranteed all rows in the collapsed group have the same value ofmembers_count
, then we knowMIN(members_count) <=> MAX(members_count)
SELECT users.id, users.username, users.email,users.rating FROM pool_details JOIN users ON users.id = pool_details.captain_id WHERE pool_details.pool_type = 0 AND pool_details.pool_close > '2020-01-02 18:39:42' GROUP BY pool_details.captain_id ORDER BY MAX(pool_details.members_count) DESC;
members_count
is not functionally dependent, then echoing the comment from forpas, which of the possible values formembers_count
do we want to use? it's easy enough to pick out the maximum and minimum values with MAX and MIN , but maybe we want the value associated with the earliest or latestpool_close
... we're only guessing because we don;'t have a more precise specification