MySQL date query syntax - mysql

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

Related

mysql - group by the last record [duplicate]

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

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

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)

Select with 'negative' offset

I need to select 40 rows with date from today and 10 records with older date, ordered by date.
If MySQL supported negative offset, it would look like this:
SELECT * FROM `mytable` WHERE `date` >= '2013-10-29' ORDER BY date LIMIT -10, 40;
Negative offset is not supported. How can I solve the problem? Thanks!!!
Use UNION to combine two queries:
(
SELECT *
FROM mytable
WHERE date < '2013-10-29'
ORDER BY date DESC
LIMIT 10
) UNION ALL (
SELECT *
FROM mytable
WHERE date >= '2013-10-29'
ORDER BY date
LIMIT 40
)
ORDER BY date -- if results need to be sorted

Most common hour query?

I have this table:
ID(INT) DATE(DATETIME)
Under the DATE column there are a lot of different dates, and I want to figure out the most common hour between all the rows of the table, regardless of the day.
How can I do that with a MySQL query?
SELECT HOUR(date) AS hr, COUNT(*) AS cnt
FROM yourtable
GROUP BY hr
ORDER BY cnt DESC
LIMIT 1
relevant docs: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_hour
Try this -
SELECT HOUR(`DATE`) AS `hour`, COUNT(*)
FROM `table`
GROUP BY `hour`
You could do a query like:
SELECT COUNT(daterow) AS occurrences FROM table GROUP BY daterow ORDER BY occurrences DESC LIMIT 1;
SELECT COUNT( id ) , HOUR( date )
FROM test
GROUP BY HOUR( date )
ORDER BY COUNT( id ) DESC
LIMIT 1