Table user structure:
id(PK)(int)
name(varchar)
time1(int10) unixtime
time2(int10) unixtime
SELECT * FROM `user` ORDER BY `time1` DESC,`time2` DESC
+------------------------------------------------------+
| id | name | time1 | time2 |
+------------------------------------------------------+
| 12345 | Joe | 1405605785 | 1406733506 |
| 12346 | John | 1406733506 | |
| 12347 | David | | 1405684190 |
+------------------------------------------------------+
I am using this sql:
SELECT * FROM `user` ORDER BY `time1` DESC,`time2` DESC
How to combine two columns time to sort desc?
============
more example reply for sagi
+------------------------------------------------------+
| id | name | time1 | time2 |
+------------------------------------------------------+
| 12345 | Joe | 1 | 2 |
| 12346 | John | 5 | |
| 12347 | David | | 4 |
+------------------------------------------------------+
I want to sort like that (DESC)
John (time = 5)
David (time = 4)
Joe (time max value = 2)
This is called conditional ordering using CASE EXPRESSION :
SELECT * FROM `user` t
ORDER BY CASE WHEN t.time1 is null THEN t.time2 ELSE t.time1 END DESC
Could also be written as:
ORDER BY coalesce(t.time1,t.time2)
You didn't provide any expected results, and you didn't say by which column the result should be ordered in case both time1,time2 are not NULL , so I assumed you want it to be ordered by the first column. If that's not the case, replace time1 with time2 .
Try this:
ORDER BY GREATEST(t.time1,t.time2) DESC
Related
I have a table named sellingDetails.
Table Data is as follows
+--------+----------------+
| id | sellingPrice |
+--------+----------------+
| 1 | 35000 |
| 2 | 40000 |
| 3 | 30000 |
| 4 | 25000 |
| 5 | 35000 |
| 6 | 33000 |
| 7 | 25000 |
+--------+----------------+
When I query
SELECT id, sellingPrice
FROM sellingDetails
ORDER BY id DESC limit 0, 4
The above query outputs:
+--------+----------------+
| id | sellingPrice |
+--------+----------------+
| 7 | 25000 |
| 6 | 33000 |
| 5 | 35000 |
| 4 | 25000 |
+--------+----------------+
Out of the above result how I can get the MAX result i.e. 35000.
I tried using MAX(sellingprice) but it didn't work.
this question is very near to mine but it has joins whereas mine is a single table
DB Fiddle
If I use the below query
SELECT MAX(sellingprice) FROM sellingdetails
ORDER BY id DESC
LIMIT 0, 4;
I get output as 40000 which is not intended.
You can use your existing query as a Derived Table and then determine the maximum value from it.
SELECT MAX(dt.sellingPrice)
FROM
(
SELECT sellingPrice
FROM sellingDetails
ORDER BY id DESC limit 0, 4
) dt
Result
| MAX(dt.sellingPrice) |
| -------------------- |
| 35000 |
View on DB Fiddle
I have a table like this, where every status change for every character is saved.
table characters_changes
+----+--------+---------+-------+----------------------+
| id | rank | job | money | datetime |
+----+--------+---------+-------+----------------------+
| 1 | 2 | tailor | 25 | 2018-06-01 12:30:15 |
| 1 | 3 | NULL | 5 | 2018-06-02 10:50:19 |
| 1 | 2 | NULL | -5 | 2018-06-03 18:44:35 |
| 1 | NULL | tinker | 10 | 2018-06-04 04:10:12 |
| 1 | 3 | NULL | NULL | 2018-06-05 17:31:00 |
| 2 | 1 | spy | 7 | 2018-06-01 12:30:15 |
| 2 | 2 | NULL | NULL | 2018-06-02 10:50:19 |
| 2 | NULL | no job | 7 | 2018-06-03 17:31:00 |
| 3 | 3 | soldier | 12 | 2018-06-01 12:30:15 |
| 3 | 1 | NULL | -11 | 2018-06-02 10:50:19 |
+----+--------+---------+-------+----------------------+
NULL means that there was no change at corresponding attribute.
rank and job changes mean replace one with another,
while money change means adding and subtracting the sum (if not NULL). There is guaranteed at least one row per character without any NULL-s.
So I need to get a table where I could show current status of every character at the end.
With their last rank, last job and resulting sum of money. A table like this one.
table characters_status
+----+--------+---------+-------+
| id | rank | job | money |
+----+--------+---------+-------+
| 1 | 3 | tinker | 35 |
| 2 | 2 | no job | 14 |
| 3 | 1 | soldier | 1 |
+----+--------+---------+-------+
What even worse, table characters_changes is a temporary table.
datetime in it comes from another table of events.
So as it is temporary, I can only query it once. But there can be any number of characters and most likely going to be more columns like rank and job.
The whole system is needed to provide the possibility to get statuses for all characters at any given datetime by ignoring all changes after that. But that part is easy for me, so I left it out of scope of my question.
This should work, I think:
SELECT id
, CASE WHEN INSTR(ranks, '|') = 0 THEN ranks ELSE LEFT(ranks, INSTR(ranks, '|')-1) END AS rank
, CASE WHEN INSTR(jobs, '|') = 0 THEN jobs ELSE LEFT(jobs, INSTR(jobs, '|')-1) END AS job
, monies
FROM
(
SELECT id
, GROUP_CONCAT(rank ORDER BY datetime DESC SEPARATOR '|') AS ranks
, GROUP_CONCAT(job ORDER BY datetime DESC SEPARATOR '|') AS jobs
, SUM(money) AS monies
FROM characters_changes
GROUP BY id
) AS lists
;
Technically, you can do it without a subquery, but I broke it down this way for clarity. The alternative would be expressions like this:
, CASE COUNT(rank) WHEN 0 THEN NULL WHEN 1 THEN GROUP_CONCAT(rank ORDER BY datetime DESC SEPARATOR '|') ELSE LEFT(GROUP_CONCAT(rank ORDER BY datetime DESC SEPARATOR '|'), INSTR(GROUP_CONCAT(rank ORDER BY datetime DESC SEPARATOR '|'), '|')-1) END AS rank
I have a table like this:
// requests
+----+----------+-------------+
| id | id_user | unix_time |
+----+----------+-------------+
| 1 | 2353 | 1339412843 |
| 2 | 2353 | 1339412864 |
| 3 | 5462 | 1339412894 |
| 4 | 3422 | 1339412899 |
| 5 | 3422 | 1339412906 |
| 6 | 2353 | 1339412906 |
| 7 | 7785 | 1339412951 |
| 8 | 2353 | 1339413640 |
| 9 | 5462 | 1339413621 |
| 10 | 5462 | 1339414490 |
| 11 | 2353 | 1339414923 |
| 12 | 2353 | 1339419901 |
| 13 | 8007 | 1339424860 |
| 14 | 7785 | 1339424822 |
| 15 | 2353 | 1339424902 |
| 16 | 2353 | 1466272801 |
| 17 | 2353 | 1466272805 |
+----+----------+-------------+
I'm trying to get last row which is related to specific user. For example for this user id_user = 7785 I want to select this row:
| 14 | 7785 | 1339424822 |
And here is my query:
SELECT unix_time AS last_seen
FROM requests WHERE id = '7785'
ORDER BY unix_time DESC
LIMIT 1
But my query doesn't select any row. What's wrong?
SQL fiddle
Also as a note, can you please tell me should I create single index on id_user and uinx_time or should I create a multiple columns index on those two columns (id_user, unix_time)?
You are using the wrong column (id instead of id_user — or vice versa):
SELECT unix_time AS last_seen
FROM requests WHERE id_user = '7785'
ORDER BY unix_time DESC
LIMIT 1
Let a sub-query return each id_user with it's highest unix_time. Join with that result.
select t1.*
from tablename t1
join (select id_user, max(unix_time) as unix_time
from tablename
group by id_user) t2
on t1.id_user = t2.id_user and t1.unix_time = t2.unix_time
Will return all users and their latest login.
Add WHERE id_user = '7785' if info about a single user is wanted.
In the WHERE condition you are comparing id with id of id_user.
Your mistake is at line two, it should be like:
SELECT unix_time AS last_seen
FROM requests WHERE id_user = '7785'
ORDER BY unix_time DESC
LIMIT 1
You have:
WHERE id = '7785'
If you want the row: | 7 | 7785 | 1339412951 |
You need something like:
SELECT TOP 1 unix_time AS last_seen
FROM requests WHERE id_user = '7785'
ORDER BY unix_time DESC
This will take the top result of the query where the user_ID equals '7785'. The 'ORDER BY unix_time DESC' puts the values with the highest unit time at the top so it will by the last request that user has had.
You can use below query it will help you
SELECT SUBSTRING_INDEX(id,',',1) AS id ,SUBSTRING_INDEX(id_user,',',1) AS id_user, unix_time FROM
(SELECT GROUP_CONCAT(id ORDER BY unix_time DESC ) AS id, GROUP_CONCAT(id_user ORDER BY unix_time DESC ) AS id_user ,MAX(unix_time) AS unix_time FROM test_71 GROUP BY id_user
HAVING id_user='7785' ) t ;
I have a MySQL table which contains a number of products. What I want to do is sort the table by one particular column (most of the values begin with numbers for example: 1st, 2nd), etc. However, since some records do not have a value for this column, when I try to sort, the table automatically puts empty rows FIRST.
I am looking for a way to sort the row ASCENDING, but only insert blank records at the end of the sorted records, if that makes sense?
Any help would be most gratefully received!
select * from table
order by if(field = '' or field is null,1,0),field
This is one of the most effective method
ASC Order
SELECT * FROM user ORDER BY name IS NULL, name ASC
Expected Result:
+----+--------+------------+
| id | name | date_login |
+----+--------+------------+
| 3 | david | 2016-12-24 |
| 2 | john | NULL |
| 4 | zayne | 2017-03-02 |
| 1 | NULL | 2017-03-12 |
DESC Order
SELECT * FROM user ORDER BY name IS NULL, name DESC
Expected Result:
+----+--------+------------+
| id | name | date_login |
+----+--------+------------+
| 4 | zayne | 2017-03-02 |
| 2 | john | NULL |
| 3 | david | 2016-12-24 |
| 1 | NULL | 2017-03-12 |
Hi all and thanks in advance.
I have a small problem which can not resolve, I have this table, and I want to sort by date and group it (but I only show 1 row per idCAT)
| id | idcat | name | date |
| 1 | 3 | xx | 2011-01-02 |
| 2 | 4 | xf | 2011-01-02 |
| 3 | 3 | cd | 2011-01-01 |
| 4 | 1 | cg | 2011-01-04 |
| 5 | 4 | ce | 2011-01-06 |
would like to stay that way, try in a way but I can not
| 2 | 4 | xf | 2011-01-02 |
| 3 | 3 | cd | 2011-01-01 |
| 4 | 1 | cg | 2011-01-04 |
Order by ID
Thank's a one friend the work.
SELECT id, idcat, name, date FROM (SELECT * FROM data ORDER BY idcat, date ) m GROUP BY idcat
I can't test conveniently atm, but try this:
SELECT FIRST(id), idcat, FIRST(name), FIRST(date) AS d FROM myTable GROUP BY idcat ORDER BY d;
Note the use of the FIRST calls to pick the first row in the table with any particular idcat.
If you are trying to get groupings by the idcat, then sorted by date:
select id, idcat, name, date from myTable group by idcat order by date;