I am in the situation where i want to match a date range with another date range, it might be simple but i am stuck at it.
Below is table structure
Table - lifecycles
life_id
life_start_date
life_end_date
then a few records as below
1 - 07/23/2013 - 07/24/2013
2 - 07/15/2013 - 07/25/2015
3 - 03/10/2013 - 03/10/2014
Now i want to search these records by date range and want to see if some life exists in that range; e.g. i want to find the lives between 08/01/2013 - 01/01/2014
As expected result it should select the life#2 and life#3
How can this be done with MySQL query?
Any help is highly appreciated.
This query should do it:
SELECT
*
FROM
lifecycles
WHERE
str_to_date(life_start_date, '%m/%d/%Y') <= '2014-01-01'
AND str_to_date(life_end_date, '%m/%d/%Y') >= '2013-08-01';
Which basically means life hasn't started before the end of the range you are looking for, and life didn't end before the range start.
Since you keep dates in VARCHAR format, you need to use str_to_date function, which is bad since MySQL won't be able to utilize any possible indexes you have on start_date or end_date columns.
This might help you.
SELECT SUM( IF( '2014-01-02' BETWEEN from_date AND to_date, 1, 0 ) ) AS from_exist,
SUM( IF( '2014-02-12' BETWEEN from_date AND to_date, 1, 0 ) ) AS to_exist
FROM date_range
So based on the results you can check whether date is between existing date range or not.
So you want to exclude lifes that are ended BEFORE 08/01/2013 and the ones that are not started AFTER 01/01/2014. This should work:
SELECT *
FROM lifecycles as alive
WHERE NOT EXISTS (
SELECT 1
FROM lifecycles as dead
WHERE dead.life_id = alive.life_id
AND (str_to_date(life_start_date, '%m/%d/%Y') > '2014-01-01'
OR str_to_date(life_end_date, '%m/%d/%Y') < '2013-08-01'))
Related
I have a table that contains tasks, each task has a date_start and date_finish field.
I need to construct a query which will take a passed in date and return all rows if that passed in date falls between the date_start and date_finish.
Does this make sense?
I have been trying to use standard date type querys such as:
SELECT *
FROM project_task
WHERE project_task.date_start >= '2013-10-10' AND project_task.date_finish <= '2013-10-10'
but it doesn’t return the correct results and using BETWEEN does not work either because I need it to take into account both fields (date_start and date_finish) not just the one.
I think it may only be the WHERE part of the query I need.
You've made a simple mistake, you got the order of your operators wrong:
SELECT *
FROM project_task
WHERE
project_task.date_start <= '2013-10-10' -- start should before the test date
AND
project_task.date_finish >= '2013-10-10' -- and finish after the test date
Explanation
If the date checked is between date_start and date_finish, then we must have reached at last the start date. We could have a later date too. That means the
date_start will be lower or equal than the date checked
And the second check said: the finish date musn't have passed. So
date_finish has to be greater or equal than the date checked.
With your original query you will only get projects that start and end on '2013-10-10'.
Demo
DECLARE #Now datetime = '2013-10-10T00:00:00'
SELECT *
FROM project_task a
WHERE #Now >= a.Date_Start
AND #Now < isnull(a.Date_Finish, '9999-12-31T00:00:00')
im using a query to get data between dates but for some reason it does not pull the data of the last date selected here is my query:
SELECT * FROM order WHERE status = "completed" AND orderdate >= ? AND orderdate <= ? ORDER BY orderid DESC
Im using is equal to or less then... but still?
what am i doing wrong ?
SELECT * FROM order WHERE status = "completed" AND date(orderdate) >= date(?) AND date(orderdate) <= date(?) ORDER BY orderid DESC
It happened with me also, but in my case instead of passing a date I was querying using a datetime variable, Please make sure you are querying with date variable only.
Make sure that orderdate is date as well as your query parameter is also date, or use appropriate function to convert them in date, than query.
Your dates are actually datetimes - so you are actually, in the case of the upperbound, saying "12 midnight" on whichever date you choose. Hence, if it tries to test a value at say 10am in the morning, it fails as being outside the range.
Either set the upperbound date one day forward, or explicitly only test the date part of the datetime...
im having a problem where i cant think of a solution, maybe im having a bad table-structure or i just dont know enough about mysql select commands to think of a good solution. Maybe you can help me out:
So i got a table that has a Column with the Date-format (yyyy-mm-dd) i wanted to select all upcoming dates so i did:
SELECT * WHERE date >= now.
This worked kinda well but i also got "dates" where only the year is entered (2014-00-00) i also wanted to select these but "now" is already bigger so i made another column with the year only and if the month, date or both arent known i will use 0000-00-00 and the Column "year" now i could select like this:
SELECT * WHERE date >= now AND year >=now(year)
Now all entrys with 0000-00-00 wont be selected. If i use OR the entrys from last year will be shown.
So thats my problem, is there any way i can change my table so i can have entries with only the year or only year and month and of course all together? I already considered get rid of the date-format and use simple INT with seperated columns for year, month and date. But i think i will have the same problem.
Sometimes i just want to do a capsuled select like
SELECT *
WHERE (date >= now AND year >= now(year))
OR date == "0000-00-00" (i know that this doesnt work)
If I understood your problem correctly, you could use this request:
WHERE (date >= now OR year > now(year))
There is probably a simpler way though, that would preserve your design, like initializing at January 1st (01-01) instead of 00-00
I think you can use this code:
$_SESSION['month'] = //set here your selected month
$_SESSION['year'] = //set here your selected year
SELECT * FROM table WHERE DATEPART(m,date) >= '".$_SESSION['month']."' AND DATEPART(yyyy,year) >= '".$_SESSION['year']."' AND date <> '0000-00-00'
Change your table structure format. Actually just allow for that field to have null value when not entered. By default it will be null then. You shouldn't be storing 0000-00-00 as a value for Date type field. I would rather leave it as null , or as suggested in some of previous answers, initialize it with some other date. It would be much easier to manipulate with database then.
the problem is that half of you write is not MySQL and your database schema is terrible...
You have the following problems:
column data date does not have the date data type.
To fix it, you need to add a cast to the select statement eg. cast(datecolumn as date)
select * from table where cast(datecolumn as date) >= '2014-01-10';
the way to use now date is using the now function.
select now(), date(now());
result> 2014-01-10 11:11:36, 2014-01-10
select * from table where cast(datecolumn as date) >= date(now());
Because your datecolumn is not a date (2014-00-00 is not a valid date), you need to use string manipulation to extract the year.
select substring('2014-01-01', 1,4)
result> 2014
select * from table where substring(datecolumn, 1,4) = year(now());
The comparassion operator is = and not ==
the select statement syntax looks like this (pay attention because you are missing the table in your statement)
select * from [Table] where [column] = condition ...
You probably need or instead of ands, therefore your query should look like this:
select * from FooTable where
cast(datecolumn as date) >= date(now())
or substring(datecolumn, 1,4) >= year(now())
or datecolumn = '0000-00-00'
You should use something like phpmyAdmin or mySQL workbench to test your sql queries before try to use them on php, java or whatever is your programing language.
I have a table that stores seasonal address dates:
addressStartDate, addressEndDate
I'm trying to find people whose seasonal addresses were historically active in May, but I'm not quite sure how to format it. I just can't seem to conceptualize how to build the query based on the two date fields. The "was active" part is the part I'm having issues with.
The years for the dates in this case are all stored as 1000, since the seasonal address switch happens at the same time every year. So what I'm looking for is people whose addresses were active between DATE '1000-05-01' and DATE '1000-05-31' - I hope this suffices to describe my issue
Try this
SELECT *
FROM yourtable
WHERE addressStartDate >= '1000-05-01'
AND addressEndDate <= '1000-05-30'
Perhaps:
SELECT *
FROM mytable
WHERE addressStartDate <= ? AND addressEndDate <= ?
Are you looking for something like this:
SELECT addressStartDate, addressEndDate, otherfields
FROM yourTable
WHERE addressStartDate >= '1000-05-01'
AND addressEndDate < '1000-06-01'
Or depending on the interpretation of your question, if an address date just needs to exist in the month, perhaps something like this:
SELECT addressStartDate, addressEndDate, otherfields
FROM yourTable
WHERE addressStartDate < '1000-06-01'
AND addressEndDate >= '1000-05-01'
Depending on how you're storing your data (with or without time), instead of using BETWEEN, I prefer using >= and < as needed.
If you want active for the whole month of May, then:
select *
from t
where t.StartDate <= date('1000-05-01') and t.StopDate >= date('1000-05-31')
If you want active for any days in May:
select *
from t
where t.StartDate <= date('1000-05-31') and t.StopDate >= date('1000-05-01')
The StopDate limits may be off by one, depending on whether or not the date of the stop date is considered an active date.
This may also be complicated by whether your data goes by the calendar year, because you have a problem with your data structure. StartDate can be larger than StopDate, which would imply a year wrap. To handle year wraps, try this:
select *
from t
where (t.StartDate < t.StopDate and t.StartDate <= date('1000-05-01') and t.StopDate >= date('1000-05-31')) or
(t.StartDate > t.StopDate and ( t.StartDate <= date('1000-05-01') or t.StopDate >= date('1000-05-31')))
I have the following data in my table. BTW ... this is a DD/MM/YYYY format:
Date
18/09/2012
17/09/2012
13/09/2012
11/09/2012
10/09/2012
09/09/2012
25/08/2012
24/08/2012
The result what I want are:
Date
18/09/2012
13/09/2012
11/09/2012
09/09/2012
25/08/2012
The rule:
It starts from the latest date (18/09/2012) and check the next one down (17/09/2012). If there is a date then removed that from the list because it requires to have 1 day apart. Then goes to 13/09/2012 and then check 12/09/2012 and didn't find and then move to next one so on and so on. Basically you can't have date close each other (min 1 day apart).
Now I can do this on cursor if it's on TSQL however since I'm working on MySQL, is there any such thing in MySQL? Or perhaps any sub-queries approach that can solve this query?
I'm appreciated your feedback.
Try this solution -
SELECT date FROM (
SELECT
date, #d := IF(#d IS NULL OR DATEDIFF(#d, date) > 1, date, #d) start_date
FROM
dates,
(SELECT #d:=null) t
ORDER BY
date DESC
) t
WHERE start_date = date
The subquery finds out start days (18, 13, 11...), then WHERE condition filters records. Try to run the subquery to understand how it works -
SELECT
date, #d := IF(#d IS NULL OR DATEDIFF(#d, date) > 1, date, #d) start_date
FROM
dates,
(SELECT #d:=null) t
ORDER BY
date DESC
SELECT
"MyTable1"."Date"
FROM
"MyTable" AS "MyTable1"
LEFT JOIN "MyTable" AS "MyTable2" ON
ADDDATE("MyTable1"."Date", INTERVAL 1 DAY) = "MyTable2"."Date"
WHERE
"MyTable2"."Date" IS NULL
ORDER BY
"MyTable1"."Date" DESC
As long as I know about mysql query will be quit tricky and buggy if some how you manage to write the one. I suggest go for cursor, here is the syntax of the cursor,
here is the syntax of the cursor