MYSQL Show one row only in same ID based on Timestamp - mysql

How can I select one row only in same ID?
This is my MySQL Code
Select * from logoutdetails ORDER BY LogInTime DESC LIMIT 1;
This is my Table
--------------------------------
| ID | LogInTime |
--------------------------------
| 07 | 2017-01-25 14:41:32 |
| 08 | 2017-01-25 14:33:22 |
| 07 | 2017-01-25 14:26:28 |
| 08 | 2017-01-25 14:18:56 |
--------------------------------

If you are satisfied with taking the most recent timestamp from each ID then you can try this:
SELECT ID, MAX(LogInTime) AS LogInTime
FROM logoutdetails
GROUP BY ID
ORDER BY ID
You could also use MIN() in place of MAX(), if you wanted to retain the earliest login time.
If the logoutdetails table had other columns and you wanted to select those too, you would have to use a subquery to first identify the maximum ID records and then join back to your original table. Something like this:
SELECT t1.*
FROM logoutdetails t1
INNER JOIN
(
SELECT ID, MAX(LogInTime) AS max_login_time
FROM logoutdetails
GROUP BY ID
) t2
ON t1.ID = t2.ID AND
t1.LogInTime = t2.max_login_time

Group by the id to get only unique ones. Then you have to decide which date you want to get for each id. Use max() to get the latest date for each
Select id, max(LogInTime) as LogInTime
from logoutdetails
group by id

Related

Get last 3 rows from SQL table without duplicates of a row

Lets say we have a table that looks like this:
+---------------+----------------+-------------------+
| ID | random_string | time |
+---------------+----------------+-------------------+
| 2 | K2K3KD9AJ |2022-07-21 20:41:15|
| 1 | SJQJ8JD0W |2022-07-17 23:46:13|
| 1 | JSDOAJD8 |2022-07-11 02:52:21|
| 3 | KPWJOFPSS |2022-07-11 02:51:57|
| 1 | DA8HWD8HHD |2022-07-11 02:51:49|
------------------------------------------------------
I want to select the last 3 entries into the table, however they must all have separate ID's.
Expected Result:
+---------------+----------------+-------------------+
| ID | random_string | time |
+---------------+----------------+-------------------+
| 2 | K2K3KD9AJ |2022-07-21 20:41:15|
| 1 | SJQJ8JD0W |2022-07-17 23:46:13|
| 3 | KPWJOFPSS |2022-07-11 02:51:57|
------------------------------------------------------
I have already tried:
SELECT DISTINCT id FROM table ORDER BY time DESC LIMIT 3;
And:
SELECT MIN(id) as id FROM table GROUP BY time DESC LIMIT 3;
If you're not on MySQL 8, then I have two suggestions.
Using EXISTS:
SELECT m1.ID,
m1.random_string,
m1.time
FROM mytable m1
WHERE EXISTS
(SELECT ID
FROM mytable AS m2
GROUP BY ID
HAVING m1.ID=m2.ID
AND m1.time= MAX(time)
)
Using JOIN:
SELECT m1.ID,
m1.random_string,
m1.time
FROM mytable m1
JOIN
(SELECT ID, MAX(time) AS mxtime
FROM mytable
GROUP BY ID) AS m2
ON m1.ID=m2.ID
AND m1.time=m2.mxtime
I've not test in large data so don't know which will perform better (speed) however this should return the same result:
Here's a fiddle
Of course, this is considering that there will be no duplicate of exact same ID and time value; which seems to be very unlikely but still it's possible.
Using MySql 8 an easy solution is to assign a row number using a window:
select Id, random_string, time
from (
select *, Row_Number() over(partition by id order by time desc) rn
from t
)t
where rn = 1
order by time desc
limit 3;
See Demo

Mysql Query to find the last transaction date with the purchased item from Purchase_history table

Table: purchase_history having all details of users
Fields are : id,uid, purchase_date, item_id, item_size, item_color
where id is a primary key.
There are many rows for an similar uid. e.g.
id | uid | purchase_date | item_id | item_size | item_color
1 | 200 | 2016-10-22 | 1021 | 3 | red
2 | 122 | 2016-08-02 | 21 | 1 | black
3 | 200 | 2016-05-01 | 222 | 1 | blue
4 | 101 | 2016-01-07 | 102 | 1 | red
So now I want a single query to get the last transaction date, item_id and uid group by uid. I used below query:
select uid, max(purchase_date), item_id from purchase_history group by uid;
it gives me correct uid and purchase date but the item id is not picked from the last row. It is coming from the first row. Is there any way that we can find the item id from the last row with uid and purchase_date?
Try this:
select uid, max(purchase_date) as date, item_id from purchase_history group by uid ORDER by date desc,item_id desc
Make sure that you item_id type is an integer.
You can find max of purchase date for each user in a subquery and join it with the main table like so:
select t1.uid, t1.purchase_date, t1.item_id
from purchase_history t1
inner join (
select uid, max(purchase_date) purchase_date
from purchase_history
group by uid
) t2 on t1.uid = t2.uid
and t1.purchase_date = t2.purchase_date;
NOTE: It'll give multiple rows for a uid, if there are rows with multiple max dates.
Use correlated subquery:
SELECT uid, purchase_date, item_id
FROM purchase_history p1
WHERE purchase_date = (
SELECT MAX(purchase_date)
FROM purchase_history p2
WHERE p2.uid = p1.uid
);
try this query
select * from (select * from purchase_history order by purchase_date asc) purchase_history group by uid;

MAX function in MySQL does not return proper key value

I have a table called tbl_user_sal:
| id | user_id | salary | date |
| 1 | 1 | 1000 | 2014-12-01 |
| 2 | 1 | 2000 | 2014-12-02 |
Now I want to get the id of the maximum date. I used the following query:
SELECT MAX(date) AS from_date, id, user_id, salary
FROM tbl_user_sal
WHERE user_id = 1
But it gave me this output:
| id | user_id | salary | from_date |
| 1 | 1 | 2000 | 2014-12-02 |
Which is correct as far as the max date being 2014-12-02, but the corresponding id is not correct. This happens for other records as well. I used order by to check but that was not successful either. Can anyone shed some light on this?
Note: Its not necessary that max date will have max id, according to my needs. Records can have max date but id may be older.
If you only want to retrieve that information for a single user, which you seem to, because of your WHERE clause, just use ORDER BY and LIMIT:
SELECT *
FROM tbl_user_sal
WHERE user_id = 1
ORDER BY date DESC
LIMIT 1
If you want to do that for every user, however, you will have to get a little bit fancier. Something like that should do it:
SELECT t2.id, user_id, date
--find max date for each user_id
FROM (SELECT user_id, MAX(date) AS date
FROM tbl_user_sal
GROUP BY user_id) AS t1
--join ids for each max date/user_id combo
JOIN tbl_user_sal AS t2
USING (user_id, date)
--limit to 1 id for every user_id
GROUP BY
user_id
You are missing group by clause Try this:
select max(awrd_date) as from_date,awrd_id
from tbl_user_sal
where awrd_user_id = 106
group by awrd_id
What I believe you should do here is have a subquery that pulls the max date, and your outer query looks for the row with that date.
It looks like this:
SELECT *
FROM myTable
WHERE date = (SELECT MAX(date) FROM myTable);
Additional things may need to be added if you want to search for a specific user_id, or get the largest date for each user_id, but this gives your expected results for this example here.
Here is the SQL Fiddle.

Sql Query to retain max 2 duplicate records

I have the following data:
Name ID Date
Dave | 123 | 1-2-2011
Jim | 123 | 1-3-2011
Mike | 123 | 1-10-2011
Bill | 111 | 1-2-2011
Henry | 222 | 1-3-2011
Larry | 222 | 1-4-2011
I need a delete query to reduce this to:
Jim | 123 | 1-3-2011
Mike | 123 | 1-10-2011
Bill | 111 | 1-2-2011
Larry | 222 | 1-4-2011
i.e. I want to keep the two latest records for each ID.
I tried this:
Delete FROM UserTable a
WHERE
Date <> (SELECT MAX(Date) FROM UserTable b WHERE a.ID = b.ID)
AND ID IN (SELECT ID FROM UserTable GROUP BY ID HAVING COUNT(*) > 1)
but this retains only the latest 1 unique records.
Try something of the sort:
SELECT col1, col2, col3, COUNT(*)
FROM (SELECT DISTINCT * FROM your_TableName) AS T1
GROUP BY col2, col3
try using this code below depending on what you want to request try using ASC or DESC
SELECT column_name,column_name
FROM table_name
ORDER BY column_name,column_name ASC|DESC;
Try also reading up on your sql http://www.w3schools.com/sql/sql_orderby.asp
Partition over can be used to retain more than one duplicate.
delete from UserTable
where (id, date) in (
select id,date from (
select id,date,
row_number() over (partition by id order by date desc) as temp
from UserTable)
where temp > 2
);
This query adds another column with row number partitioned by the id, ordered by date and then deletes those records which have row number greater than 2.

MySQL View to do a Group by after an Order by

the "t_example" table :
id | date
---------------
1 | 2001-05-09
1 | 2005-11-05
1 | 2000-08-19
2 | 2010-10-30
2 | 2002-12-10
2 | 2009-07-29
3 | 2003-02-15
3 | 2012-04-20
I would like to create a view that returns the following result (the max date for each id):
id | date_id
---------------
1 | 2005-11-05
2 | 2010-10-30
3 | 2012-04-20
MySQL don't allow to do a subquery with order by in view, and when I use an other view for the subquery, the group by ignore the order by in the subquery.
The following query returns the expected result:
select id, date
from (select id, date from t_example order by id asc, date_id desc) p
group by p.id
But when I use it in a views it does't work:
view1 (subquery) : select id, date from t_example order by id asc, date_id desc;
view2 : select id, date from view1 group by view1.id;
Is there any other solution?
This should work for you
SELECT id, MAX(date) AS date FROM t_example GROUP BY id;
This is using the AS syntax to keep your column name succinct (otherwise it would be MAX(date))
select id,max(date)
from your_table
group by id