Say I want to SELECT all records between two dates plus one record before and one record after that date? All records are ordered by date.
You could use a union combined with the limit statement. Something like what's below (untested, don't have access to mysql).
(select column from table where datefield > startdate and datefield < stopdate)
union
(select column from table where datefield < startdate order by datefield desc limit 1)
union
(select column from table where datefield > stopdate order by datefield limit 1)
This will give you the next row regardless of where it falls date-wise.
Thanks for syntax fix, ponies.
(select * from t where date < start_date order by date desc limit 1)
union (select * FROM t WHERE date between start_date and end_date)
union (select * from t where date > end_date order by date asc limit 1)
You can use functions to add or subtract values, like this:
select * from table where field1 < ADDDATE( CURTIME() , INTERVAL 1 DAY)
Check this link where there are some examples.
SELECT *
FROM table
WHERE date BETWEEN DATE_ADD(current_date(), INTERAL -1 DAY)
AND DATE_ADD(current_date(), INTERVAL 1 DAY);
Related
As the title says, I have a table with a date column. I am trying to retrieve all rows between 2 dates as well as X number of rows before the beginning date ordered by date.
Take a select * from table order by date DSC
20200201
20200101
20191201
20191101
20191001
20190901
20190801
20190701
I want between 20200201 and 20191201 and the previous 3 rows(not knowing the date)
result
20200201
20200101
20191201
20191101
20191001
20190901
my current query returns a random set of high dates between the union for some reason:
(SELECT * FROM Table WHERE Date BETWEEN 20200201 AND 20191201 ORDER BY Date ASC)
UNION
(SELECT * FROM Table WHERE Date < 20191201 ORDER BY Date DESC LIMIT 3)
Any idea where I am going wrong?
One method uses lead():
select t.*
from (select t.*,
lead(date, 3) over (order by date) as next_date_3
from t
) t
where (date < '202o-02-01' and (next_date_3 >= '2020-02-01' or next_date_3 is null) ) or
(date between '2020-02-01' and '2019-12-01')
I tried this query and it worked for me:
(SELECT * FROM Table WHERE Date BETWEEN 20191201 AND 20200201 ORDER BY Date ASC)
UNION
(SELECT * FROM Table WHERE Date < 20191201 ORDER BY Date DESC LIMIT 3)
The first select shows me:
20191201
20200101
20200201
The second select shows me:
20191101
20191001
20190901
The issue was as jarlh pointed out, the order of the subquery's were not kept(thats why things were jumbled) and a simple ORDER BY of the whole UNION fixed this. I did not try Gordon's response as this solved my issue so:
(SELECT * FROM Table WHERE Date BETWEEN 20191201 AND 20200201)
UNION
(SELECT * FROM Table WHERE Date < 20191201 ORDER BY Date DESC LIMIT 3)
ORDER BY Date ASC
Thank you
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
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)
I have a table with some fields and a timestamp field named timestart.
What I would like to do is select all the records from my table where the field timestart is 21 days from now.
But how can I do this?
you can have this with. if you want exact equals to timestamp. use =
SELECT *
FROM table
WHERE date = DATE_ADD(NOW(), INTERVAL 21 DAY)
ORDER BY date DESC
you can achive the same by using
SELECT *
FROM table
WHERE date = DATE_ADD(NOW(), INTERVAL 21 DAY)
ORDER BY date DESC
The datediff function seems to meet the bill:
SELECT *
FROM my_table
WHERE DATE_DIFF (timestart, CURRENT_DATE()) >= 21
You can use this:
SELECT *
FROM table
WHERE date >= (NOW() - INTERVAL 21 DAY)
ORDER BY date DESC
LIMIT 20
Should be fairly self-explanatory; any idea why I can't do:
select user_id from my_table where created_at<date_add(min(created_at), INTERVAL 1 MINUTE)
I'm trying to only return rows that have been created within a minute of the earliest timestamp. Thanks!
You should use HAVING instead of WHERE when dealing with aggregate functions... Still, your query will be a bit more complex, I guess:
SELECT user_id,
created_at, (
SELECT DATE_ADD(MIN(created_at), INTERVAL 1 MINUTE)
FROM my_table
) AS earliest
FROM my_table t1
HAVING created_at < earliest;
Here's a SQLFiddle to play with. )
Try this:
SELECT user_id
FROM my_table
WHERE created_at < DATE_ADD((SELECT MIN(created_at) FROM my_table), INTERVAL 1 MINUTE)
SELECT user_id FROM my_table
WHERE created_id <
(
SELECT (min_dt + INTERVAL 1 MINUTE) mindt FROM
(SELECT MIN(created_id) min_dt FROM my_table) A
);