GROUP BY after ORDER BY - mysql

I need to do GROUP BY after ORDER BY. I don't understand why MySQL doesn't support that.
This is my code:
SELECT
`pages`.`id`,
`contents`.`id_language`,
[...]
[...]
ORDER BY
FIND_IN_SET(`languages`.`id`, '3') DESC
[the GROUP BY]
The results will be something like this:
id | id_language | ...
1 3
1 1
2 3
2 5
2 1
I need to group by ID, I need only the first result and I need to save in a view. I can't use a SUBQUERY because of that.
The result need to be:
id | id_language | ...
1 3
2 3
Note: Don't get confused by id_language = 3, because it isn't a rule.

SELECT id, idl
FROM (SELECT
`pages`.`id` as id,
`contents`.`id_language` as idl,
[...]
[...]
ORDER BY
FIND_IN_SET(`languages`.`id`, '3') DESC
) d
GROUP BY d.id

Group By will group result sets, and is generally used for aggregation.
Order By is the way that results are sorted.

You may want an additional column in your original query that you GROUP BY, along with whatever you're currently grouping by. That column, when grouped, could then be used to order afterward. For instance:
SELECT
SUM(IF(`languages`.`id` = 3, 1, 0)) AS languageOrder,
`pages`.`id`,
`contents`.`id_language`,
[...]
[...]
[GROUP BY...]
ORDER BY languageOrder DESC
I would intend for languageOrder to be positive for groups that contain language #3, 0 otherwise. So groups that contain language 3 will be at the top.

Very amusing, try
select * from your_table
where id_language=3
order by id;
As far I can tell, the rule set is id_language=3,
which make no differences from using where

Related

How to order SELECT results based on the IN() list order?

I am having some troubles ordering item using MySQL, example
$USER_INPUT = '10,4';
$SQL = "SELECT * FROM table Where ID IN ($USER_INPUT)";
If I use this query, it will order the items EG: 4 and 10, instead of the user input 10 and 4.
you can create custom order by in order by like the below
ORDER BY FIELD(column_name,'1,5,6,7,10,43,867')
May be your query returns in a descending manner try to place an order by clause at the end of the query
ORDER BY id ASC
I used
SELECT A.ID, A.Name
FROM Properties A
WHERE A.ID IN (110,105,104,106)
Order By case A.ID
when 110 then 0
when 105 then 1
when 104 then 2
when 106 then 3 end
and it worked.

How to check if the column value are the same among multiple record with one sql

suppose there is a table
id desc
1 a
1 b
1 c
1 a
2 a
2 a
what I want to do is to show a mix of desc if the desc under the same id are different, otherswise show the value of the desc. Just like below
id desc
1 a/b/c
2 a
How could I do it in one sql ?
enter code here
I think you want group_concat() with the distinct modifier:
select id, group_concat(distinct `desc` separator '/') as `desc`
from t
group by id;
Note that desc is a bad name for a column because it is a SQL keyword (think order by). It is best to avoid grammatical elements when choosing names.

mysql order by clause not working with my query

Lets say I have the following mysql query
SELECT friends.id, sum(if(friends.online =1,1,0)) AS online_friends, ...,...
FROM some_table
GROUP BY id
ORDER BY sum(if(friends.online =1,1,0)) ASC;
What I want is to sort my resulting table bases on online_friends either ASC or DESC, the problem is that this query does not sort them by online_friends.
Can anyone help me fixed my query?
This is an example of the results
id group online_friends
-- ------- ----------------
1 west 5
2 east 3
3 north 7
4 south 2
I want to sort the results based on online_friends
Your query should work:
SELECT friends.id, sum(if(friends.online =1,1,0)) AS online_friends, ...,...
FROM friends
GROUP BY id
ORDER BY sum(if(friends.online =1,1,0)) ASC;
However, I would write it as:
SELECT friends.id, sum(friends.online = 1) AS online_friends, ...,...
FROM friends
GROUP BY id
ORDER BY sum(friends.online = 1) ASC;
You can also change the order by to:
ORDER BY online_friends
If you find that it still doesn't work, then please set up a SQL Fiddle so we can see what is happening.
You may try this:
SELECT friends.id, groups, sum(friends.online) AS online_friends
FROM some_table
where friends.online = 1
GROUP BY friends.id, groups
ORDER BY friends.online ASC;
I assumed that online and offline are having the value as 1 and 0 respectively.

specify order in order BY

this is a simple question but I have been googling long time now but no results.
SELECT * FROM `target` WHERE `week_id`=23
and `ini_id`=2
ORDER BY `region_id`
When I order this query it is either in ASC or DESC.
Can I specify a sequence for region_id like (5,6,7,1,2,3,4)
You can use FIELD for that:
SELECT *
FROM `target`
WHERE `week_id`= 23
and `ini_id`= 2
ORDER BY FIELD(`region_id`,5,6,7,1,2,3,4)
You should be able to use FIND_IN_SET:
SELECT *
FROM `target`
WHERE `week_id`=23
and `ini_id`=2
ORDER BY FIND_IN_SET(`region_id`, '5,6,7,1,2,3,4')
Not directly, no, but you can get the resultset ordered per the specification d using an expression, such as:
ORDER BY CASE WHEN region_id IN (5,6,7) THEN 1 ELSE 2 END, region_id
That CASE expression is deriving a value from the region_id. So rows with a region_id of 5, 6 or 7 get assigned a value of "1", and all other rows get assigned a "2". When we order by that, all the 5,6,7 region_id rows come first, then everything else.
The next step is to then order by the region_id.
Two ways to do this:
Order by Calculated
You could do order by, but with a calculated value so that you get the order you want.
For example:
select * from data order by (region_id+5)%10;
SQL Fiddle: http://www.sqlfiddle.com/#!2/5f80da/2
Using Union
(select * from data where region_id > 4)
UNION
(select * from data where region_id < 5)
SQL Fiddle: http://www.sqlfiddle.com/#!2/09fe1/1

mysql SQL: specific item to be first and then to sort the rest of the items

Lets say I have the table below.
I want to get all the friends, but I want the id 5 to be the first item in the list. I don't care about the order that I receive the rest of the items.
The desired query result will be:
friends
-------
id name
5 nahum
1 moshe
2 haim
3 yusuf
4 gedalia
6 dana
How can I do this?
using Mysql 5.1.x.
Thanks!
select id,name
from friends
order by id=5 desc
(given you don't care about order of the rest, otherwise, e.g. rest by id asc)
select id,name
from friends
order by id=5 desc, id asc
Try this:
select id,name
from friends
order by case when id=5 then -1 else id end
if you have more then one you can do:
select id,name
from friends
order by case when id in (5,15,25) then -1 else id end,id
I can't access a MySQL now to test, so it might be reversed... but you can use the fact that Booleans also sort, and that you can have several sort fields.
SELECT ... ORDER BY id != 5, id
(you might have to write id = 5, I can't remember if TRUEs sort before or after FALSEs.)
EDIT: Oh, I just read that you don't care about the order of the rest, in which case I heartily recommend #Richard's answer.
You can use field() in MySQL.
select id,name from friends order by field(id,5,id)
The 1st parameter in field() means the field you want to sort with, the rest is ordering.
So 5 will be sort first, and the rest from id (without 5). You can do like field(id,5,1,3,id) if you want 5,1,3 to be in front.
5 can be choose to sort at last by field(id,id,5). The 2nd id will exclude 5 from it also.
If you want to do the same for UNION query, for example if you have:
select id,name
from friends
UNION
select id,name
from friends
order by id=5 desc
... you would get an exception in PostgreSQL:
Only result column names can be used, not expressions or functions. HINT: Add the expression/function to every SELECT, or move the UNION into a from clause
To get around this, you would use the following:
select id,name, (id=5) AS is_five
from friends
UNION
select id,name, (id=5) AS is_five
from friends
order by is_five DESC, id DESC
The expression (id=5) would return 't' OR 'f', depending on whether your column value is equal or not to the expected value (5), so the order by would first order the 't' columns, then the rest.
You should use MySQL's ORDER BY FIELD clause to solve this. Although, the answer has been accepted on this, here's a better solution.
select 1 id, 'Zeta' order_col union all
select 2 id, 'Alpha' order_col union all
select 3 id, 'Gamma' order_col union all
select 4 id, 'Phi' order_col union all
select 5 id, 'Delta' order_col union all
select 6 id, 'Delta' order_col union all
select 7 id, 'Alpha' order_col union all
select 8 id, 'Gamma' order_col union all
select 9 id, 'Zeta' order_col union all
select 10 id, 'Phi' order_col
order by field (order_col, 'Alpha', 'Gamma', 'Phi', 'Delta', 'Zeta'), id;
This is better than
id=something, order by id asc
order by case when something then 1 when something_else then 2 end desc
This is a little ugly because it has code duplication, but it does the trick:
select .... where id = 5
union
select .... where not id = 5