I get a lot of answers when it comes to how MySQL sorts results but none seems to address my specific issue. Hope I didn't miss the answer somewhere else here on stackoverflow.
I have an SQL query that looks like this:
SELECT id, something FROM sometable WHERE
id=1 OR id=2 OR id=5 OR
id=6 OR id=100 OR id=1000
OR id=4
Now I need it to return the results in the specific order it has been selected. The results should look like this in this specific order:
1
2
5
6
100
1000
4
Will MYSQL display the returned records in this particular order the way I selected them? I cannot use ORDER BY because I need them the exact way I selected them in the first instance. A simple test confirms that it is returned in this way but from reading elsewhere I get the idea that you cannot trust the way results are being returned in specific order when ORDER BY is not used.
You can use FIELD() function. In your application code, where you will be creating this SQL dynamically, you can build the SQL string in the same order for FIELD(), as in your WHERE clause.
FIELD(str,str1,str2,str3,...)
Returns the index (position) of str in the str1, str2, str3, ... list.
Returns 0 if str is not found.
Now, the FIELD(id, 1,2,5,6,100,1000,4) function will return 0 if the id is not in (1,2,5,6,100,1000,4).
So, if we use ORDER BY FIELD(id, 1,2,5,6,100,1000,4) only, other non-matching rows will appear at the top. So, we can use If() function to return 1 for the other non-matching rows, and 0 for the matched rows.
Now, we can utilize one more level of ordering by FIELD(id, 1,2,5,6,100,1000,4). This will ensure that the matched id(s) appear first in the order as specified in the Field() function.
SELECT id, something FROM sometable WHERE
id=1 AND id=2 AND id=5 AND
id=6 AND id=100 AND id=1000
AND id=4
ORDER BY IF(FIELD(id, 1,2,5,6,100,1000,4) = 0, 1, 0) ASC,
FIELD(id, 1,2,5,6,100,1000,4) ASC
Related
I have the following MySql Query:
SELECT * FROM myTable ORDER BY FIELD(
priority,1,2,3,4,5,6,7,8,....,300,0),date_fixed ASC, sno DESC";
In fact, i need to display record ordered by priority ASC but also want to keep all the record having the priority = 0 at the end of the any other numerical value. The above query working fine but I think its not worth to write values starting from 1 to 300 and at the end i just put 0.
My Question is that any shortcut way to achieve the ResultSet as Orderby priority ASC and keeping the 0th priorities at the end?
Need help with mysql request.
I make a request and I want to order result by the field ID.
ID for exemple: 1,2,3,4,5,6,7,8,9
But I need that it would be ordered like this: 6,3,1,2,4,5,7,8,9
Is there any solution in mysql to forcibly put ID=6 in 1st place, ID=3 in 2nd...?
or I want the impossible)
Use CASE expression in ORDER BY clause.
Query
select * from `your_table_name`
order by case `id` when 6 then 1 when 3 then 2 else 3 end, `id`;
Find a demo here
Use:
ORDER BY FIELD(id, 6,3,1,2,4,5,7,8,9)
The FIELD function returns the position of the first value in the remaining list.
I have one such sql:
select name from A where id in (23,24,22,23)
When I run it in Navicat, the result only have one result of 23.
My question is, how to keep the number and order of the query results remains the same as (23,24,22,23).
If you want to maintain the order of the result then use order by clause like
select name from A
where id in (23,24,22)
order by id;
Again, assuming that id is a primary key column in your table A then there will be only one row with id = 23. How do you expect the same row to get repeated automatically unless you make it explicit by using a UNION ALL
If you really really want to fetch the records like this, you can use field function to get 23,24,22 and order by this sort:
select name from A where id in (23,24,22) order by field(id, '23,24,22')
then use union all get another 23:
(select name from A where id in (23,24,22) order by field(id, '23,24,22'))
union all
select name from A where id = 23
I asked the question about multiple rows in a previous thread, but now I need to know about a single row. This is an example query:
SELECT * FROM table1 WHERE this = 5 LIMIT 1
But if there is no rows found then I would it to then find the record with a different value:
SELECT * FROM table1 WHERE this = 1 LIMIT 1
So what I want is, find a row with this having the value of 5, if not found then default to finding a row with a value of 1. How do I do that in a single query? Would an OR statement work like so?
SELECT * FROM table1 WHERE this = 5 OR this = 1 LIMIT 1
Would the order of the OR statement try to find any row with the value of 5, if found then it will stop and return the row? IF not found then look for 1 and then return that row? If not then how do I do this with a single query where it searches for one value, if not found defaults to find another value?
I was thinking this query:
SELECT * FROM table1 WHERE this IN(5,1) ORDER BY this ASC LIMIT 1
However this query would always return the value with 1 if both values were found right? So I tried this:
SELECT * FROM table1 WHERE this IN(5,1) ORDER BY this DESC LIMIT 1
But this would always return the value of 5 if both rows were found correct?
Your question appears to prioritize the search for 5 and only if not found then search for 1. Hence your second solution fits the requirement fine. It will return the value of 5 irrespective of if 5 is only found or both 5 and 1 exist.
the 2nd option
SELECT * FROM table1 WHERE this IN(5,1) ORDER BY this DESC LIMIT 1
Try this
SELECT *
FROM table1 tab
WHERE tab.this = IF((SELECT COUNT(*)
FROM table1
WHERE this = 5) > 0, 5, 1)
The query inside the IF is checking for the count.
I am not sure about the performance but I think this solves your issue.
I have a column of states, and, depending on the query, I want to order by results by a particular state, then by id (Asc or Desc, depending). For instance, I might want to show all rows with state "HI", sorted by ID desc, and then all the other rows, sorted by id desc.
I was hoping I could do this in one query, rather than getting all my favored state results, and then getting the rest. Can I?
How about:
SELECT id, state
FROM sometable
ORDER BY IF(state = 'HI', 0, 1) ASC, id DESC;
This will sort 'HI' rows first. If you want them last, change the ASC to DESC.
You have two options:
do a union
write a function and use it to order rows by
In the first case, you could do something like
select 1 as res_order, ...
...
where state like 'hi%'
union
select 2 as res_order, ...
...
where state not like 'hi%'
order by res_order asc, id desc
In the second case, you could do something like
select my_function(state, "hi") as row_order, ...
...
order by row_order
where the function returns lower values for matching states.
The code is off the top of my head: it might need some tweaking to make it runnable.