I have a tble which has fromdate and todate fields. I have been trying to fetch data for a particular date.
Below is the query that i have been trying with no luck,
SELECT *
FROM install
WHERE customer != ''
AND billtype = 'QUARTERLY'
AND (STR_TO_DATE (fromdate, ' %m-%Y') + INTERVAL 3 MONTH=STR_TO_DATE('01-01-2018', ' %m-%Y'))
For Example
if he user selects january month of 2019, any row with fromdate + 3 months should come up.
Any suggestions
Try using date inequalities, which avoid the calls to STR_TO_DATE:
SELECT *
FROM install
WHERE
customer <> '' AND
billtype = 'QUARTERLY' AND
DATE_ADD(fromdate, INTERVAL 3 MONTH) BETWEEN '2018-01-01' AND '2018-01-31';
FYI your current syntax is off, which is why it won't work as you expected.
But actually, a better way to express your logic would be to subtract 3 months from January 2018:
SELECT *
FROM install
WHERE
customer <> '' AND
billtype = 'QUARTERLY' AND
fromdate BETWEEN '2017-10-01' AND '2017-10-31';
This version of the query is also SARGable, meaning that an index involving the fromdate column could still be used.
Related
all,
trying to adapt the below query to get this for the last business day of say month may, june or whatever?
select distinct
month(createddate),
year(CreatedDate),
id,
value1,
vaue2,
createddate,
count( distinct id)
from
table
and value2 IN ('harry','sally')
AND createddate > LAST_DAY( '2020-05-21') ## i need last business day here for may.
AND createddate < '2020-06-01' ## i need first day of next month here
group by month(createddate),
year(CreatedDate), id,value1, value2,createddate
ive not used mysql in a while, is there a way i can use a function or stored procedures to find this out? if so how
*** by business day i mean working day, not a weekend***
Presumably, you want to avoid weekend days. So:
(createddate > last_day('2020-05-21') and dayofweek(last_day('2020-05-21') between 2 and 6 or
createddate > last_day('2020-05-21') - interval 1 day and dayofweek(last_day('2020-05-21') = 7 or
createddate > last_day('2020-05-21') - interval 2 day and dayofweek(last_day('2020-05-21') = 1
)
id start_date interval period
1 2018-01-22 2 month
2 2018-02-25 3 week
3 2017-11-24 3 day
4 2017-07-22 1 year
5 2018-02-25 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). requirement is, 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.
I am using mysql 5.7. I found a way 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 but its a performance killer and we can't do populate virtual records every time a client request comes.(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.
SELECT b.*
FROM (SELECT a.*,
CASE
WHEN period = 'week' THEN MOD(Datediff('2018-07-22', start_date), 7 * intervals)
WHEN period = 'month'
AND Day('2018-07-22') = Day(start_date)
AND MOD(Period_diff(201807, Extract(YEAR_MONTH FROM start_date)), intervals) = 0 THEN 0
WHEN period = 'year'
AND Day('2018-07-22') = Day(start_date)
AND MOD(Period_diff(201807, Extract(
YEAR_MONTH FROM start_date)) / 12,
intervals) = 0 THEN 0
WHEN period = 'day' THEN MOD(Datediff('2018-07-22', start_date) , intervals)
end filters
FROM kml_subs a)b
WHERE b.filters = 0;
But I need to do this for a period of dates not a single date. Any suggestions or solutions will be much appreciated.
My desired result shoud be like..
if i give two dates.say 2030-05-21 & 2030-05-27. due dates falls under those 6 dates between(2030-05-21 & 2030-05-27) will be shown in the result.
id
1
4
My question is different from Using DATE_ADD with a Column Name as the Interval Value . I am expecting a dynamic way to check due dates based on start_date
Thanks, Kannan
In MySQL, it would seem that a query along these lines would suffice. (Almost) everything else could and should be handled in application level code...
SELECT *
, CASE my_period WHEN 'day' THEN start_date + INTERVAL my_interval DAY
WHEN 'week' THEN start_date + INTERVAL my_interval WEEK
WHEN 'month' THEN start_date + INTERVAL my_interval MONTH
WHEN 'year' THEN start_date + INTERVAL my_interval YEAR
END due_date
FROM my_table;
In my project one of the tasks is to run a daily report of all new reports and jobs that have been conducted in the preceding 24 hours easy..
However they throw in a funny in terms of the repair crews do not work over the weekend however reports could naturally still come in. So Monday morning a report will be produced show all reports from the past 3 days eg fri - mon and any repairs conducted on the fri similar to the code below.
One solution which I find unpracticle is to show two date fieds and the user selects fri & mon date like code I produced below for another function.
SELECT `defect_Id`, `job_Id`, `date_On_Task`, `description`, `resolved`
FROM `job`
WHERE `date_On_Task` >= '$date1'
AND `date_On_Task` <= '$date2'
AND `repair_Team` = '$repair_Team'
AND `resolved` = 3"
I would like to be able to use if statement with nested sql statements if day = Monday show * <3days if not show * <1 day.
The select statement is an issue I'm struggling to find any information on a variable of a day for example on click CURDATE() would select current date but can SQL convert a date to a day?
You could get rid of both date pickers from your application.
For that you could apply your logic in WHERE clause using CASE statement:
WHERE
CASE WHEN WEEKDAY(CURRENT_DATE) = 0
THEN `date_On_Task` = CURRENT_DATE - INTERVAL 3 DAY
ELSE `date_On_Task` = CURRENT_DATE - INTERVAL 1 DAY
END
WEEKDAY() function returns 0 for Monday and will cause the following where clause to apply on Mondays:
WHERE `date_On_Task` = CURRENT_DATE - INTERVAL 3 DAY
If the function returns anything else (from 1 to 6 meaning Tuesday to Sunday) get jobs that have been performed yesterday.
Substracting days from a particular date is straightforward. You could use DATE_SUB() or substract INTERVAL like that:
<DATE HERE> - INTERVAL <NUMBER HERE> DAY
Your full query would look:
SELECT `defect_Id`, `job_Id`, `date_On_Task`, `description`, `resolved`
FROM `job`
WHERE
CASE WHEN WEEKDAY(CURRENT_DATE) = 0
THEN `date_On_Task` = CURRENT_DATE - INTERVAL 3 DAY
ELSE `date_On_Task` = CURRENT_DATE - INTERVAL 1 DAY
END
AND `repair_Team` = '$repair_Team'
AND `resolved` = 3
Kind of like this(?):
WHERE
[date_On_Task] BETWEEN
CASE
WHEN DATENAME(DW, GETDATE()) = 'Monday' THEN CAST(GETDATE() - 3 AS date)
WHEN DATENAME(DW, GETDATE()) = 'Sunday' THEN CAST(GETDATE() - 2 AS date)
ELSE CAST(GETDATE() - 1 AS date)
END
AND
CAST(GETDATE() AS date)
How can I get the result of the current year using SQL?
I have a table that has a column date with the format yyyy-mm-dd.
Now, I want to do select query that only returns the current year result.
The pseudo code should be like:
select * from table where date is (current year dates)
The result should be as following:
id date
2 2015-01-01
3 2015-02-01
9 2015-01-01
6 2015-02-01
How can I do this?
Use YEAR() to get only the year of the dates you want to work with:
select * from table where YEAR(date) = YEAR(CURDATE())
Using WHERE YEAR(date) = YEAR(CURDATE()) is correct but it cannot use an index on column date if exists; if it doesn't exist it should.
A better solution is:
SELECT *
FROM tbl
WHERE `date` BETWEEN '2015-01-01' AND '2015-12-31'
The dates (first and last day of the year) need to be generated from the client code.
When I tried these answers on SQL server, I got an error saying curdate() was not a recognized function.
If you get the same error, using getdate() instead of curdate() should work!
--========= Get Current Year ===========
Select DATEPART(yyyy, GETDATE())
SELECT id, date FROM your_table WHERE YEAR( date ) = YEAR( CURDATE() )
SELECT
date
FROM
TABLE
WHERE
YEAR (date) = YEAR (CURDATE());
If the date field contains a time component, you want to include December 31 so you have to go to January 1 of the next year. You also don't have to use code to insert dates into the SQL. You can use the following
SELECT * FROM table
WHERE date BETWEEN MAKEDATE(YEAR(CURDATE()), 1) AND MAKEDATE(YEAR(CURDATE())+1, 1)
This will give you January 1st of the current year through January 1st at midnight of the following year.
As #Clockwork-Muse pointed out, if the date field does not contain a time component, you would want to exclude January 1 of the following year by using
WHERE date >= MAKEDATE(YEAR(CURDATE()), 1) AND date < MAKEDATE(YEAR(CURDATE())+1, 1)
You can do this using SQL DATE_FORMATE(). like below:
SELECT
date
FROM
TABLE
WHERE
DATE_FORMAT(date, '%Y') = YEAR (CURDATE());
SELECT [ID]
,[datefield]
FROM [targettable]
WHERE DATEPART(YYYY, [datefield]) = (SELECT TOP 1(MAX(DATEPART(YYYY, [datefield])))
FROM [targettable]
)
/*
This will find the newest records in the table regardless of how recent the last time data was entered.
To grab the oldest records from the table do this
SELECT [ID]
,[datefield]
FROM [targettable]
WHERE DATEPART(YYYY, [datefield]) = (SELECT TOP 1(MIN(DATEPART(YYYY, [datefield])))
FROM [targettable]
)
*/
I'm using a custom PHP function to produce a visual calendar for a single month that blocks out dates based on a table that contains an start date, and an duration - For example:
...This is produced by data saying that the table should be blocked out for 4 days from the 14th, and 7 days from the 27th.
The query looks something like this:
SELECT GROUP_CONCAT(DATE_FORMAT(start_date,'%d'),':', event_duration) AS info
FROM events
WHERE YEAR(start_date = '2012'
AND MONTH(start_date) = '07'
ORDER BY start_date
(You could safely ignore the group concat and return the data as individual rows, that doesn't really matter).
I'm looking for a modification to the query that would block out dates at the start of the month IF an event starts in the previous month, but its length takes it into the following.
For instance - in the above example, the event on the 27th is actually scheduled to last 7 days in the database, so if I ran the query for MONTH(start_date) = '08' I'd like to say the first two dates blocked out, which they wouldn't currently be, because the start date that would block it out is not in the month being selected.
I'm fairly sure there's a subquery or something in there to grab the rows, but I just can't think of it. Any takers?
EDIT
The answer from Salman below pointed me in the directon I wanted to go, and I came up with this as a way of getting carryovers from the previous month to show as '1st' of the month with the number of remaining days:
SELECT IF(MONTH(start_date) < '08', '2012-08-01', start_date) AS starter,
IF(MONTH(start_date) < '08', duration - DATEDIFF('2012-08-01',start_date), duration) AS duration
FROM EVENTS
WHERE YEAR(start_date) = '2012'
AND (MONTH(start_date) = '08' OR MONTH(start_date + INTERVAL duration DAY) = '08')
Obviously a lot of variables there to replace in PHP, so maybe there's an even better way?
Original Answer:
Assuming that the month in question is 2012-07, you need this query:
SELECT column1, column2, columnN
FROM `events`
WHERE `start_date` <= '2012-07-01'
AND `start_date` + INTERVAL `duration` DAY > '2012-07-01'
ORDER BY start_date
Revised Answer:
Apparently you need a query that checks for overlapping (or conflicting) dates. The example dates are 2012-07-01 through 2012-08-01 and the query is:
SELECT *
FROM events
WHERE '2012-08-01' > start_date
AND start_date + INTERVAL duration DAY > '2012-07-01'
ORDER BY start_date
To constrain the start date and interval, you can use SELECT ... CASE statement:
SELECT
CASE
WHEN start_date < '2012-07-01' THEN '2012-07-01'
ELSE start_date
END AS start_date_copy,
CASE
WHEN start_date < '2012-07-01' THEN duration - DATEDIFF('2012-07-01', start_date)
ELSE duration
END AS duration_copy,
FROM ...
The answer I was looking for, thanks to the other contributor for pointing me in the right direction and enabling me to solve it!
This is based on $yyyy and $mm coming from PHP (in my case, into a function call), and selecting individual rows rather than grouping:
SELECT start_date, duration
FROM reservations
WHERE YEAR(start_date) = '".$yyyy."'
AND MONTH(start_date) = '".$mm."'
UNION
SELECT '".$yyyy."-".$mm."-01',
duration - DATEDIFF('".$yyyy."-".$mm."-01',start_date)
FROM reservations
WHERE YEAR(start_date) = '".$yyyy."'
AND MONTH(start_date) < '".$mm."'
AND MONTH(start_date + INTERVAL duration DAY) = '".$mm."'
ORDER BY start_date