I have a table with a column called "myorder". I want to only order the first 5 elements in ascending order by using the column "myorder" and then the rest of the elements ordererd by id in descending order. I've tried but I don't seem to get this 100%. I have created a sqlfiddle with this simple example. Can anybody help me?
The order in the sqlfiddle should be: Blue, Brown, Yellow, Red, Green, Orange, Gray, Black, White.
maybe try
SELECT * from tbl ORDER BY IF(myorder=0, 2147483647, myorder) ASC, id DESC
if by "first 5" you mean ones with nonzero myorder
Append this to the end of your sql statement:
ORDER BY FIELD(id, 3,4,5,1,2,9,8,7,6)
This will manually sort the results based on the id field in the specified order getting the colours in order.
Alternatively you could:
ORDER BY FIELD(NAME, BLUE,BROWN,YELLOW......)
Union does not preserves order, at least not in all databases.
To get this done you need to select a fake column and use order on the results (total)
Here is a solution:
(
SELECT Id, myorder, myorder as fake, name from tbl WHERE myorder!=0) UNION
(SELECT id, myorder, 2000 as fake,name from tbl WHERE myorder=0) ORDER BY fake asc, id desc
This Will work in any case, as long as you keep the fake number high enough.
Can we have NULL value instead of zero when myorder is not specified?
If so we can do this:
SELECT * from tbl ORDER BY -myorder DESC, id DESC
Fiddle:
http://sqlfiddle.com/#!2/ef9ee/4
Hint on forcing nulls to sort last: MySQL Orderby a number, Nulls last
Use a CASE statement and the following trick (for example):
SELECT *,
CASE myorder
WHEN 0 THEN id
ELSE 99999999 - myorder
END AS ord
FROM tbl
ORDER BY ord DESC
SQL Fiddle
Related
First of all, I am using MySQL. When I make the following query:
SELECT CodE,sum(tiempo) AS 'tiempo total'
FROM Participa
GROUP BY CodE
ORDER BY 'tiempo total' DESC LIMIT 1;
it shows me the first line of my table instead of the MAX value. However, If I make the following query:
SELECT CodE,sum(tiempo)
FROM Participa
GROUP BY CodE
ORDER BY 2 DESC LIMIT 1
I get the correct result.
I have just changed the alias 'tiempo total' for somthing that should be equivalent.
How it´s possible?
Only use single quotes for string and date constants -- never for column aliases. So:
SELECT CodE, sum(tiempo) AS `tiempo total`
FROM Participa
GROUP BY CodE
ORDER BY `tiempo total` DESC
LIMIT 1;
You are ordering by a constant string, not the name of a column. Hence, if you get the maximum in your query, it would be a total accident.
Note: You can get around these issues by giving columns names that never need to be escaped:
SELECT CodE, sum(tiempo) AS tiempo_total
FROM Participa
GROUP BY CodE
ORDER BY tiempo_total DESC
LIMIT 1;
Easier to type, too.
size color in_stock
----- ----- -----
small red 0
large red 1
xlarge red 1
When I'm using GROUP BY size,color, the first row with in_stock 0 is being chosen over the second row. Is there any way to have GROUP BY always give priority for rows with in_stock 1, rather than in_stock 0?
The short answer is: No
I suspect (because you don't supply your original query) that you are using something like this:
SELECT size,color, in_stock
FROM atable
GROUP BY size,color
MySQL allows a GROUP BY clause to have just a few non-aggregating columns - BUT it only does so by virtue of a server setting
see: http://dev.mysql.com/doc/refman/5.0/en/group-by-handling.html
If you use this "feature" there is no control over what data is chosen in the other non-aggregating columns.
You should NOT use this "feature" of MySQL because if the server settings turn off this extension your queries will no longer work.
You could do something like this instead:
SELECT size,color, MIN(case when in_stock = 1 then in_stock else NULL end)
FROM atable
GROUP BY size,color
You can use syntax as per below
select size, color, in_stock, ....other fields...
from yourtable
where ...conditions if any....
group by size,color
order by in_stock desc;
Order by always work after group by, so if you want to first order then group. you can use below query-
select size, color, in_stock
from
(
select size, color, in_stock, ....other fields...
from yourtable
where ...conditions if any....
order by in_stock desc
) as a
group by size,color;
If you GROUP BY column(s) and also return a non aggregate column that is not in the GROUP BY clause, then which row that columns value is taken from is not defined. It might be the first one, it might be the last one. It might change depending on storage engine, or anything else.
If you specifically wanted the 2nd one you could do something like this:-
SELECT size, color, SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(in_stock ORDER BY FIELD(size, 'small', 'large', 'xlarge')), ',', 2), ',', -1)
FROM atable
GROUP BY size,color
I have a simple query, but I would like to see the results in a specific way. I would like to see 'N/A' at the top of the result, without having to result to "Case When Then"
Select *
From Ordertype
Results:
Car21
Car34
Bus42
N/A
Thanks,
There are no 'overrides' for ORDER BY, if you want the specific order you're asking for, you'll have to use the CASE:
SELECT type
FROM OrderType
ORDER BY
CASE
WHEN type = 'N/A' THEN 1
ELSE 2
END
,type
If you want an arbitrary order that is not tied directly to the structured of a column (alphabetical/numerical) but rather to it's importance which only you know in your head it can be useful to add a Rank column to your table.
Column1 Rank
Car21
Car34 2
Bus42 1
N/A 99
then you can do
select Column1
from Table
order by rank desc, column1
This will put highly ranked items first then low ranked items, then when rows don't have a rank it will sort them alphabetically by column1
You can try this:
SELECT * FROM ordertype ORDER BY ID DESC
to see the newest ones 1st
Lets say I have the following query.
SELECT stringdata FROM table ORDER BY FIELDS( stringdata, 'tg','nk','mg','pl') asc;
For some reason I'm getting the results at the very bottom. How can I get the query to put the results starting from 'tg' at row 1 rather than the last row in the results?
Not only that but there's more than one 'tg' in the data, I'd like it to sort it in this expected output:
stringdata
__________
'tg'
'tg'
'tg'
'nk'
'nk'
'mg'
'mg'
'mg'
'pl'
So far using ORDER BY Fields() is only sorting one instance of the data rather than all.
Using desc instead of asc in the query works as expected. I get 'pl' on the first row, then 'mg', 'nk', etc.
Normally the FIELD clause in ORDER BY works something like
SELECT * FROM table ORDER BY FIELD(field, high_priority, second_high,
,....., low_priority);
So in your query, the sorting took place as you mentioned and when you gave the ASC it printed from the lowest_priority. So, for your case, if you want tg at the top, you can either reorder the priority in the FIELDS or as you have already tried use desc
If you want first rows with 'tg', then rows with .... then with 'pl' and then all the rest sorted (ASC or DESC) use this:
SELECT stringdata
FROM table
ORDER BY FIELD( stringdata, 'pl','mg', 'nk', 'tg') DESC
, stringdata ASC --- or DESC
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.