I have ItemsRent table,
ID | ParentID | SubID | StartDate | EndDate |
--------------------------------------------------------------------
1 | 100 | 102 | 2014-09-09 17:40:00 | 2014-11-09 17:40:00 |
2 | 70 | 73 | 2014-08-09 14:20:00 | 2014-12-09 13:40:00 |
The dates are in sql format.
My input dates are:
InputStartDate: 2014-09-09 18:00:00
InputEndDate: 2014-10-09 13:47:00
And i want to return the best row only of the dates are between two dates. So for example:
Lets call StartDate as S, and EndDate as E.
And input dates will be InputStartDate as IS, and InputEndDate as IE.
S E
|----------------|
IS IE
|XXXXXXX--------|
Any suggestions ?
This query will produce a result matching your illustration. It will find all rows where any time at all was spent between InputStartDate and InputEndDate, and output a modified date range that is clamped by InputStartDate and InputEndDate.
SELECT ID, ParentId, SubId,
MAX( InputStartDate, StartDate ) AS Date_Start,
MIN( InputEndDate, EndDate ) AS Date_End
FROM `itemsRent`
WHERE InputStartDate <= EndDate AND InputEndDate >= StartDate
Normally, I would say to use the BETWEEN operator, but since you are storing both the start and end dates in the table, this would get more complicated than it needs to be. If you assume that the start date being stored is before the end date, you only need to perform two checks.
SELECT * FROM `itemsRent` WHERE `StartDate` > 1410285600 AND `EndDate` < 1410356820
This verifies that the start date of the item takes place after the specified start date. The issue with this is that it does not check if it takes place before the end date. Instead of explicitly writing this check, you can make sure of this by checking that the item's end date takes place before the specified end date.
NOTE: Might cause issues if the start date does not occur before the end date. If this is a possibility, then you will need to explicitly write these checks. This would be a good case in which to use the BETWEEN operation.
Why not just pull out the max end date in the table as the high date?
SELECT *
FROM itemsRent
WHERE (InputStartDate BETWEEN startdate AND end date)
AND (InputEndDate BETWEEN startdate AND enddate);
Your query is currently looking for rows whose EndDate is earlier than your provided StartDate or after your provided EndDate. I don't think that is what you want.
If you want rows that both StartDate and EndDate are between your provided dates (lets call them your-start-date and your-end-date), your query should be something like:
SELECT * FROM `itemsRent` WHERE `StartDate` > your-start-date AND `StartDate` < your-end-date AND `EndDate` > your-start-date AND `EndDate` < your-send-date
Related
I have the following table with measured values:
datetime | water | air | conductivity | ...
2021-07-17 16:44:39 | 13,9 | 18,6 | 357 | ...
I am currently querying the values for a period of time:
SELECT * FROM kn1 WHERE datetime > TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 month)) ORDER BY datetime
Now I don't want to get every value, just the highest value of each day.
In general, I can query the highest value through
SELECT MAX(water) FROM kn1 WHERE datetime > TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 month)) ORDER BY datetime
But this way I get the highest value for the entire period. But I would like to get the highest value for each day in the period.
How can I do this?
Thanks in advance
Use GROUP BY:
SELECT DATE(datetime), MAX(water)
FROM kn1
WHERE datetime > CURDATE() - INTERVAL 1 month)
GROUP BY DATE(datetime);
Note that I modified the WHERE clause to simplify it. Presumably, you don't date about the current time, just the date, so this uses the current date. Second, there is no need for TIMESTAMP, and third, I find interval arithmetic to be simpler without additional functions.
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html
We can see that some functions do not like incomplete dates:
Some date functions can be used with “zero” dates or incomplete dates such as '2001-11-00', whereas others cannot.
I want to subtract two dates like this:
SELECT DATEDIFF(CURRENT_DATE(), birthdate)
birthdate is a DATE column according to the phpMyAdmin console.
But some of the birth dates don't have the month or day, example '1874-00-00'. You cannot get the days difference because the days are not known.
Is there a way to tell it to assume Jan 1 or something? Or would I need to resort to some building the date up myself so it recognizes it?
I really just need the approximate number of years difference. But I get NULL.
Thanks.
Use only YEAR from your field & do simple subtraction:
SELECT YEAR(NOW())-YEAR(birthdate) FROM YOUR_TABLE_NAME;
It will work both for valid & invalid date
If you have dates like '1874-00-00' then the data type of the column is VARCHAR unless you have disabled NO_ZERO_IN_DATE mode which is enabled by default.
I really just need the approximate number of years difference
If the year is always included in your dates and it is 4 digits at the start then all you need is to subtract your date form the current year:
SELECT birthdate,
YEAR(NOW()) - birthdate AS age
FROM tablename
MySql will do implicit conversion of the birthdate to an integer which will be just the year.
For this sample data:
CREATE TABLE tablename(birthdate VARCHAR(20));
INSERT INTO tablename(birthdate) VALUES
('1950-05-15'), ('1960-08-00'), ('1970-00-00');
the result will be:
| birthdate | age |
| ---------- | --- |
| 1950-05-15 | 70 |
| 1960-08-00 | 60 |
| 1970-00-00 | 50 |
Or if you want to be more precise when the birthdates are valid dates:
SELECT birthdate,
COALESCE(
TIMESTAMPDIFF(YEAR, birthdate, NOW()),
YEAR(NOW()) - birthdate
) age
FROM tablename
See the demo.
id start_date interval period
1 1/22/2018 2 month
2 2/25/2018 3 week
3 11/24/2017 3 day
4 7/22/2017 1 year
5 2/25/2018 2 week
the above is my table data sample. start_dates will be expired based on interval and period(i.e id-1 will have due date after 2 months from the start_date, id-2 will have due after 3 weeks vice versa). period is enum of (day,week,month,year). Client can give any period of dates. let's say 25-06-2026 to 13-07-2026 like that.. I have to return the ids whose due dates falls under that period.I hope i made my question clear.
Here what i have done to resolve this. I am using mysql 5.7. I found ways to achieve this with recursive CTE's.(not available in mysql 5.7). and there is a way to achieve this by populating virtual records by using inline sub queries along with unions and its a performance killer and there is restriction of population of records.(like given in the link Generating a series of dates) I have reached a point to get results for a single date which is very easy. Below is my query(in oracle)
select id
from (select a.*,
case
when period='week'
then mod((to_date('22-07-2018','dd-mm-yyyy')-start_date),7*interval)
when period='month' and to_char(to_date('22-07-2018','dd-mm-yyyy'),'dd')=to_char(start_date,'dd')
and mod(months_between(to_date('22-07-2018','dd-mm-yyyy'),start_date),interval)=0
then 0
when period='year' and to_char(to_date('22-07-2018','dd-mm-yyyy'),'dd-mm')=to_char(start_date,'dd-mm')
and mod(months_between(to_date('22-07-2018','dd-mm-yyyy'),start_date)/12,interval)=0
then 0
when period='day'
and mod((to_date('22-07-2018','dd-mm-yyyy')-start_date),interval)=0
then 0 else 1 end filter from kml_subs a)
where filter=0;
But I need to do this for a period of dates not a single date. Any suggestions or solutions will be much appreciated.
Thanks,
Kannan
Assuming this is an Oracle question and not MySQL:
I think the first thing that you need to do is calculate when the due date is. I think a simple case statement can handle that for you:
case when period = 'day' then start_date + numtodsinterval(interval,period)
when period = 'week' then start_date + numtodsinterval(interval*7,'day')
when period = 'month' then add_months(start_date,interval)
when period = 'year' then add_months(start_date,interval*12)
end due_date
Then, using that new due_date field, you can check if the due date falls between the desired date range.
select *
from(
select id,
start_date,
interval,
period,
case when period = 'day' then start_date + numtodsinterval(interval,period)
when period = 'week' then start_date + numtodsinterval(interval*7,'day')
when period = 'month' then add_months(start_date,interval)
when period = 'year' then add_months(start_date,interval*12)
else null end due_date
from data)
where due_date between date '2018-02-25' and date '2018-03-12'
The above query checking between 2/25/18 and 3/12/18 produces the following output using your data:
+----+-------------+----------+--------+-------------+
| id | start_date | interval | period | due_date |
+----+-------------+----------+--------+-------------+
| 2 | 05-FEB-2018 | 3 | week | 26-FEB-2018 |
| 5 | 25-FEB-2018 | 2 | week | 11-MAR-2018 |
+----+-------------+----------+--------+-------------+
I need to find intersect between to date intervals for example
I have one date
2015-01-01 and 2015-03-01
and second value
2015-01-01 and 2015-01-15
I wanna get results 15. So how many days of second date is included in first date range?
Any ideas how to do it with MySql?
In MySQL you can use the following SQL statement to get what you need:
SELECT DATEDIFF(LEAST('2015-03-01 23:59:59','2015-01-15 23:59:59'),GREATEST('2015-01-01 00:00:00','2015-01-01 00:00:00'))+1 AS days;
+------+
| days |
+------+
| 15 |
+------+
This will get the date difference in days using DATEDIFF
You can use CASE for condition like below:
SELECT (CASE
WHEN '2015-01-01'>= '2015-01-01' AND '2015-04-15'<='2015-03-01'
THEN DATEDIFF('2015-01-15','2015-01-01')+1
ELSE 'out of range'
END) AS days;
You can specify your own else condition and date range.
We have a table that has a StartDate field which holds a type of datetime. There are thousands of records and I am looking for a way to find the number of days within a given result returned from this table. For instance, if my table had this data:
ID | StartDate
--------------
1 01/01/2013 09:34:54
2 01/01/2013 11:23:21
3 04/11/2013 14:43:23
4 04/11/2013 17:13:03
5 04/25/2013 18:02:59
6 07/21/2013 02:56:12
7 10/01/2013 19:43:10
Then the query should return 5 as the 2 dates on 01/01/2013 count as 1 and the same for 04/11/2013.
The only SQL I've been able to come up with is:
SELECT COUNT(DISTINCT(DATEPART(DAY, StartDate)))
FROM Stats
WHERE StartDate BETWEEN '01/01/2013' AND '12/31/2013' --This is just for filtering
But this returns 4 because it doesn't take the month into account.
Any help is appreciated.
You can CAST as date
SELECT COUNT(DISTINCT CAST(StartDate AS DATE))
FROM Stats
WHERE StartDate >= '20130101' AND StartDate < '20140101'
Also use an unambiguous date format such as yyyymmdd and >= < not BETWEEN.
Your current query would include the 31st December if there was a row with exactly the value 20131231 00:00:00 but not any with different times on that date. I doubt that is intentional.