mysql - group by the last record [duplicate] - mysql

This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Closed 3 years ago.
My table has multiple records of n_no column, and when I GROUP BY, it returns me the first record of the group, how do I get the last record?
SELECT * FROM mytable WHERE category = 16 AND status = 1 AND datetime >= "2020-01-06 00:00:00" AND datetime <= "2020-01-06 23:59:59" GROUP BY n_no ORDER BY datetime DESC LIMIT 0,30
Thanks.
[Solved by doing]
SELECT * FROM mytable WHERE (SELECT MAX(datetime) from mytable GROUP BY n_no) AND category = 16 AND status = 1 AND datetime >= "2020-01-06 00:00:00" AND datetime <= "2020-01-06 23:59:59" GROUP BY n_no ORDER BY datetime DESC LIMIT 0,30

Assuming you are using MySQL 8+, then ROW_NUMBER() can work here:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY n_no ORDER BY datetime DESC) rn
FROM mytable
WHERE category = 16 AND status = 1 AND
datetime >= '2020-01-06' AND datetime < '2020-01-07'
)
SELECT *
FROM cte
WHERE rn = 1;

You can try something like below,
SELECT * FROM mytable WHERE pk_col in (SELECT max(pk_col) FROM mytable WHERE category = 16 AND status = 1 AND datetime >= "2020-01-06 00:00:00" AND datetime <= "2020-01-06 23:59:59" GROUP BY n_no ORDER BY datetime DESC LIMIT 0,30)
Here, replace pk_col with the primary column name of your table.
Please find a sample here.

The idea of "GROUP BY" is to get categories. not to select a record.
SELECT DISTINCT n_no, datetime, category, status, etc
FROM mytable
WHERE category = 16
AND status = 1
AND datetime BETWEEN "2020-01-06 00:00:00" AND "2020-01-06 23:59:59"
ORDER BY datetime DESC
LIMIT 1
in this way you get all records from each n_no with the last date

Related

Getting all orders, where the last order ist older than a year in mySql

I have a mySQL table, which holds:
CustomerId and OrderDate
There can me multiple rows for one CustomerId
Now, I try to get the CustomerId's where only the last OrderDate is older than a year.
I try the following:
SELECT *
FROM order
WHERE OrderDate <=DATE_SUB(now(), Interval 1 Year)
GROUP BY CustomerId
ORDER BY OrderDate DESCC;
The problem here is, that I get all the rows, which are older then 1 year.
But as I said above, I try to get only the latest order, which is older than 1 year.
THX for any advise
Order the rows and limit to the last. Also, you had DESCC instead of DESC.
SELECT *
FROM order
WHERE OrderDate <=DATE_SUB(now(), Interval 1 Year)
GROUP BY CustomerId
ORDER BY OrderDate DESC
LIMIT 1;
You might also try this query:
SELECT
`CustomerId`,
`CustomerName`, // Add other fields you want returned.
MAX(`OrderDate`)
FROM `order`
WHERE `OrderDate` <= DATE_SUB(now(), Interval 1 Year)
GROUP BY `CustomerId`
ORDER BY MAX(`OrderDate`) DESC;
Also, this will return all of the related columns in the last order for each customer:
SELECT *
FROM `order` a
JOIN (
SELECT
`CustomerId`,
MAX(`OrderDate`) as `maxdate`
FROM `order`
WHERE `OrderDate` <= DATE_SUB(now(), Interval 1 Year)
GROUP BY `CustomerId`) b
ON a.`CustomerId` = b.`CustomerId` AND
a.`OrderDate` = b.`maxdate`
ORDER BY `maxdate` DESC;
Try this subquery:
select customer_id
from customer table
where order_id in(Select order_id from (select order_id from order_table (year(now())-year(order_date)) = 1 order by order_date desc limit 1))
if it doesn't work please post your table structure.
THX for all your tips.
At the end, I found my working solution:
SELECT
*
FROM order a1
INNER JOIN (SELECT
order.Id
FROM (SELECT
*
FROM (SELECT
*
FROM order
WHERE OrderDate <= DATE_SUB(NOW(), INTERVAL 1 year)
ORDER BY OrderDate DESC) AS Sub
GROUP BY Sub.CustomerId) AS a2) AS a3
ON a1.id = a3.id;

Order by multiple columns with multiple conditions

I have a table with some events like this
id----------title-----------date-------------status
1-----------birthday-------2018-03-12--------1
2-----------match----------2018-03-13--------2
3-----------anniversary----2018-03-10--------1
4-----------trip-----------2018-03-15--------1
5-----------birthday-------2018-03-17--------2
6-----------birthday-------2018-03-11--------1
Expected Result
id----------title-----------date-------------status
1-----------birthday-------2018-03-12--------1
4-----------trip-----------2018-03-15--------1
5-----------birthday-------2018-03-17--------2
2-----------match----------2018-03-13--------2
6-----------birthday-------2018-03-11--------1
3-----------anniversary----2018-03-10--------1
I need to query it like the first rows which have dates greater than today with status 1 should appear first and then the rest in desc.
Suppose today is 2018-03-11 then row with id 1 should appear first and then the rest of the rows is desc order
This is what I have tried so far
SELECT *
FROM events
ORDER BY (date > CURDATE() and status = 1) asc,
date desc
You can use multiple keys in an order by:
order by (date >= curdate() and status = 1) desc,
date desc
I believe your SQL should be something like this but is hard to say without expected results.
Query
SELECT
*
FROM
[table]
WHERE
date > CURDATE()
AND
status = 1
ORDER BY
date ASC
LIMIT 1
UNION
SELECT
*
FROM
[table]
WHERE
id NOT IN (
SELECT
id
FROM
[table]
WHERE
date > CURDATE()
AND
status = 1
LIMIT 1
)
AND
date > CURDATE()
ORDER BY
date DESC

How to query SQL on date AND time

My current table looks like this - Table is called "S"
DJ DATE
---- ------
test yyyy/mm/dd hh:mm:ss
I've worked up to the below SQL query
SELECT *
FROM `S`
WHERE `DATE` = '2017-02-27 17:00:00'
ORDER BY `S`.`DATE` DESC
LIMIT 0 , 1
Rather than having the set date and time though I would like to query based on the current date AND time. I'm using datetime type structure.
All I'm looking to do is query the current datetime to get the current name from the DJ row
Thanks!
You can use now() function to get the current datetime.
SELECT *
FROM `S`
WHERE `DATE` = now()
ORDER BY `S`.`DATE` DESC
LIMIT 0 , 1
If you want to get result for today's date, you can use curdate and date function
SELECT *
FROM `S`
WHERE date(`DATE`) = curdate()
ORDER BY `S`.`DATE` DESC
LIMIT 0 , 1
With mysql, you can use the CURRENT_TIMESTAMP() function.
SELECT *
FROM S
WHERE DATE = CURRENT_TIMESTAMP()
ORDER BY S.DATE DESC
LIMIT 0, 1
I think you want:
select s.*
from s
where date(date) = CURDATE() and
hour(date) = hour(NOW())
order s.date` DESC
limit 0, 1;

MySQL Select where column greater than or equal to closest past date from given date

TABLE
Table:
Id Date
1 01-10-15
2 01-01-16
3 01-03-16
4 01-06-16
5 01-08-16
Given two dates startdate 01-02-16 and enddate 01-05-16. I need to get the data from the table such that it returns all data between the closest past date from startdate and closest future date from enddate including the two dates. So the result will look like this.
Result:
Id Date
2 01-01-16
3 01-03-16
4 01-06-16
What I am doing
What I am doing now is fetching the whole data and removing from the array results less than closest fromdate and greater than closest enddate
What I want
What I want is to do this in query itself so that I don't have to fetch the whole data from table each time.
If you column's type is date, use union can do it:
(select * from yourtable where `date` <= '2016-01-02' order by `date` desc limit 1)
-- This query will get record which is closest past date from startdate
union
(select * from yourtable where `date` => '2016-01-05' order by `date` asc limit 1)
-- This query will get record which is closest future date from enddate
union
(select * from yourtable where `date` between '2016-01-02' and '2016-01-05')
Demo Here
Imaging your date is in YYYY-mm-dd
## get rows within the dates
SELECT * FROM tab WHERE ymd BETWEEN :start_date AND :end_date
## get one row closest to start date
UNION
SELECT * FROM tab WHERE ymd < :start_date ORDER BY ymd DESC LIMIT 1
## get one row closest to end date
UNION
SELECT * FROM tab WHERE ymd > :end_date ORDER BY ymd LIMIT 1
Try this
Select *
From
dTable
Where
[Date]
Between
(Select
Max(t1.Date)
From
dTable t1
Where
t1.date <startdate) And
(Select
Min(t2.Date)
From
dTable t2
Where
t2.date >enddate)
If Date is String, STR_TO_DATE and DATEDIFF can be used here.
SELECT id, Date
FROM tab
where
STR_TO_DATE(Date, '%d-%m-%y') BETWEEN('2016-02-01')AND('2016-05-01')
or
id = (SELECT id FROM tab
where STR_TO_DATE(Date, '%d-%m-%y') > '2016-05-01'
ORDER BY DATEDIFF(STR_TO_DATE(Date, '%d-%m-%y'), '2016-05-01') Limit 1)
or
id = (SELECT id FROM tab
where STR_TO_DATE(Date, '%d-%m-%y') < '2016-02-01'
ORDER BY DATEDIFF('2016-02-01', STR_TO_DATE(Date, '%d-%m-%y')) Limit 1)

MySQL date query syntax

If I have a date column, example "2013-05-05", how do I select the previous record? I tried
SELECT DATE, percent_change
FROM aa
WHERE DATE >2012 -12 -31
ORDER BY DATE DESC
LIMIT 1
Assuming that date is a unique key:
SELECT `date`, percentage_change FROM aa WHERE `date`>'2012-12-31' ORDER BY `date` DESC LIMIT 1;
Then, to get the previous record:
SELECT `date`, percentage_change FROM aa WHERE `date`>'2012-12-31' ORDER BY `date` DESC LIMIT 1 OFFSET 1;
And the record before that:
SELECT `date`, percentage_change FROM aa WHERE `date`>'2012-12-31' ORDER BY `date` DESC LIMIT 1 OFFSET 2;
etc.
To get the record before a given date, this should work:
SELECT DATE, percent_change
FROM aa
WHERE DATE < '2013-05-05'
ORDER BY DATE DESC
LIMIT 1
SQL Fiddle Demo