MySQL ORDER BY CASE Date ASC/DESC - mysql

I have these records on my table:
ID Win Date
1 NULL 2019-01-15
2 12 2019-01-10
3 NULL 2019-01-12
4 513 2019-01-14
I want the order to be:
win that are null first, ordered by date asc and win that are not null after, ordered by date desc
So the order would be: 3, 1, 4, 2
How can i achieve this using order by case or any other way?

You should use ORDER BY CASE ... here:
SELECT * FROM ...
ORDER BY
NOT ISNULL(Win),
CASE
WHEN Win IS NULL
THEN `Date`
ELSE DATEDIFF('9999-01-01', `Date`)
END
This should with for dates before 9999-01-01. Adjust this value if you'd have latter dates.

Try this
order by iif(win is null,1,0) DESC, Date DESC
Sorry misread the intended order try something like this
Order by iif(win is null,1,0) DESC,DateDiff(Day,'1900-01-01',Date) * iif(win is null,1,-1) DESC
the idea is to get a value that you can make negative by using an if statement

Related

How to order SQL result by the earlier/older of two dates?

Assume a simple table with three field: An user_id and two dates last_login and last_api_usage.
I would like to find inactive users by ordering the the table by the earlier of the two dates. Example:
user_id | last_login | last_api_usage
------------+---------------+----------------
1 | 2020-06-01 | NULL
2 | 2020-09-01 | 2020-03-01
3 | 2020-05-01 | 2020-08-01
Result order: 2, 3, 1
User 2 is the most active because the although he did not use the API for a while the login was September. Next is user 3 due to the API usage in August.
Of course ordering the result by two dates is not problem (...ORDER BY last_login, last_api_usage DESC) but this would return the result 2, 1, 3 and is not what is intended.
How to order by the earlier/orlder of the two dates?
You can use the least and coalesce function as follows:
ORDER BY least(last_login, coalesce(last_api_usage,last_login))
What' your RDBMS?
ORDER BY ast_login, last_api_usage DESC NULLS LAST
or use coalesce function
thank you.
OP you can union all to unpivot the column then order it.
for example:
select * from (
select user_id,use_date ,row_number()over(partition by user_id order by use_date desc) rn from (
select user_id, last_login as use_date
from [TABLE]
union all
select user_id,last_api_usage
from [TABLE]
) a ) b
where rn = 1
order by use_date
the logic is simple, combine both column into one column then filter the row with biggest date, in the following hyperlink I did not use proper date format for pseudo data but the idea is same.
here is db<>fiddle for better examine.

Order By before Group By in Mysql

I have a problem when use Order By and Group By in a query string.
I want Order By before Group By but it's don't work.
I searched and find some solution but it don't work with me:
SELECT * FROM
(
SELECT minder_id, service_type_id
FROM minder_service
WHERE minder_id = 238
AND deleted_at is null
ORDER BY service_type_id ASC
) AS t
GROUP BY t.minder_id
Run 1
SELECT minder_id, service_type_id
FROM minder_service
WHERE minder_id = 238
AND deleted_at is null
ORDER BY service_type_id ASC
Result:
Photo for Result 1
Run 2: Full
Photo for Result 2
Please have a look at.
Thanks so much.
If you want the lowest service_type_id, you can use the MIN function:
SELECT minder_id, MIN(service_type_id)
FROM minder_service
WHERE minder_id = 238 AND deleted_at IS NULL
GROUP BY minder_id
Also make sure deleted_at is really NULL for the record with service_type_id 1 if you say you expect that record.
A subquery returns an unordered set. The database doesn't have to keep the order when passing the result of a subquery to an outer query, or when performing the group by operation.
You should rethink what you're trying to do.

Select x number of records in reverse order that are lesser than a date

I have a table where date is one of the column. Assume the date is ordered by ascending order.
I am trying to fetch 7 records in ascending order that are older than a particular given date in reverse order.
Example
======================
ID Date
=======================
1 2016-09-01
2 2016-09-03
3 2016-09-07
4 2016-09-09
5 2016-09-13
6 2016-09-15
7 2016-09-19
8 2016-09-22
9 2016-09-23
Assume I want to select 3 records in ascending order that are lesser than 2016-09-15 in reverse order.
The output I would need is
************************
ID Date
=======================
3 2016-09-07
4 2016-09-09
5 2016-09-13
How can I achieve this in MySQL?
If I understand your question correctly, it should be just this:
SELECT *
FROM (
SELECT *
FROM Example
WHERE
my_date<'2016-09-15'
ORDER BY
my_date DESC
LIMIT 3
) s
ORDER BY my_date ASC
Please see a fiddle here.
This should work:
select * FROM table where date_field < 'some_date' order by date_field desc LIMIT 7
ORDER BY and LIMIT when used together could get a little tricky.
If you need records older than a date and and sorted latest first
Query suggested by #fthiella should work.
Same applies when you need records later than a date and sorted earliest first. You just have to order by date.
If you need records older than a date sorted oldest first, you cannot order by and limit in a single query.
You might have to do something like
select my_date from
(
select my_date from
my_table where my_date < '08/24/2014'
order by my_date desc
limit 7
) a
order by my_date
Outer order by desc or not based on the order you want.

MySQL Order by Date, with NULL first

I have a select statement that I would like to select 1 record from a table. The structure is:
id | start_time
--------------
1 NULL
2 2014-08-23
3 2014-09-01
I would like to select the item with a NULL start time, but if that does not exist I would like it to select the latest start_time. I have tried using ORDER with LIMIT 1, but using ORDER BY start_time either gives NULL first followed by the earliest starting, or latest starting then NULL. Is it possible to have result order 1,3,2 ?
You can use two sort expressions to get the ordering you want:
select t.*
from table t
order by (start_time is null) desc,
start_time desc
limit 1;
You can have two different ORDER BY expressions:
SELECT * from table ORDER BY (start_time IS NULL) DESC, start_time DESC;

How can I combine the following information into 1 mysql query?

DETAILS
I want to find the difference between start and stop times(duration) for each test taken then rank users according to the highest score and lowest duration for each test. Ultimately I will use PDO to do this in mysql. So far though I've just been working on the sql. I think I'm pretty close now, but am unsure how to combine the information into one query.
WHAT I'VE GOT(untested).
I have the following table called testresults
--------------------------------------------------------------------
| index | id | start | stop | score|
--------------------------------------------------------------------
| 1 | 23 | 2012-06-06 07:30:20 | 2012-06-06 07:30:34 | 100 |
--------------------------------------------------------------------
In my select statement I want to get the id and the score along with the calculated duration.
I can get duration for any test taken today with the below query.
SELECT TIMESTAMPDIFF(SECOND,stop,start) AS duration
FROM testresults WHERE `start` >= DATE(NOW())
Then I sort the results based on rank. Rank is determined according to score and duration. Top place goes to the highest score with the shortest duration.I believe I can do that with something like this:
ORDER BY score DESC, duration ASC
I only want maybe 100 entries so,
LIMIT 100
QUESTION
How can I combine the above information into 1 query?
SELECT `id`, `score`,
TIMESTAMPDIFF( SECOND, start, stop ) AS `duration`
FROM `testresults`
WHERE `start` >= DATE(NOW())
ORDER BY `score` DESC, `duration` ASC
LIMIT 100;
This will work pretty good. You'll also need to put id & score in SELECT statement.
SELECT id, score, TIMESTAMPDIFF(SECOND,stop,start) AS duration FROM testresults
WHERE `start` >= DATE(NOW()) ORDER BY score DESC, duration ASC LIMIT 100
this should work