I have a table with:
last_billed DATE DEFAULT "0000-00-00"
bill_interval varchar(10) DEFAULT "Monthly" (other values are: Quarterly, Half-yearly, Yearly)
I run a simple query, but it needs to:
ORDER BY (last_billed + bill_interval)
This should give a date which is 1 month, 3 months, 6 months or 12 months further then the last_billed date, depending on the value of bill_interval.
Now I can change bill_interval to anything if need be, if it would make the query possible.
I have no idea where to start with this. So any feedback is, as always, appreciated.
Try:
ORDER BY last_billed +
CASE bill_interval
WHEN "Montly" THEN INTERVAL 1 MONTH
WHEN "Half-Yearly" THEN INTERVAL 6 MONTH
WHEN "Yearly" THEN INTERVAL 1 YEAR
END
It would be easier if you changed the bill_interval column to a number of months, then you could do:
ORDER BY last_billed + INTERVAL bill_interval MONTH
ORDER BY DateAdd("m",
case substring(bill_interval,1,1) when 'M' then 1
when 'Q' then 3
when 'Y' then 12
end, last_billed)
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;
I want to select data from my mysql database which are older than 1 month. I tried this query. It does not work. What is the correct query?
SELECT * FROM `mails` WHERE `received_time` BETWEEN NOW() AND DATE_SUB(NOW(),INTERVAL 1 MONTH)
Try this query:
SELECT * FROM `mails` WHERE `received_time` < DATE_SUB(NOW(),INTERVAL 1 MONTH)
Your received_time column must be in datetime format like '2015-05-17 23:30:40'.
The issue is that when using a BETWEEN comparison, the lower bound must be specified first, and the upper bound last.
As a demonstration, try this query:
SELECT 2 BETWEEN 1 AND 3
, 2 BETWEEN 3 AND 1
The first expression evaluates to TRUE (returns a 1), the second expression evaluates to FALSE (returns a 0).
Just reorder the two values in the BETWEEN and you'll be good.
This will return rows that are "within" the past month:
WHERE received_time BETWEEN NOW() + INTERVAL -1 MONTH AND NOW()
That's equivalent to
WHERE received_time >= NOW() + INTERVAL -1 MONTH
AND received_time <= NOW()
If you only want rows that are "earlier" than a particular date, then don't use a BETWEEN comparison, just use an inequality comparison. To return all rows that were received over one month ago e.g.
WHERE received_date < NOW() + INTERVAL -1 MONTH
I'm trying to solve a task: I have a table containing information about ships' battles. Battle is made of name and date. The problem is to get the last friday of the month when the battle occurred.
WITH num(n) AS(
SELECT 0
UNION ALL
SELECT n+1 FROM num
WHERE n < 31),
dat AS (
SELECT DATEADD(dd, n, CAST(battles.date AS DATE)) AS day,
dateadd(dd, 0, cast(battles.date as date)) as fight,
name FROM num,battles)
SELECT name, fight, max(day) FROM dat WHERE DATENAME(dw, day) = 'friday'
I thought there must be a maximum of date or something, but my code is wrong.
The result should look like this:
Please, help!!
P.S. DATE_FORMAT is not available
Possible problem: as spencer7593 noticed - and as I should have done and didn't - your original query is not MySQL at all. If you're porting a query that's OK. Otherwise this answer will not be helpful, as it makes use of MySQL functions.
The day you want is number 4 (0 being Sunday in MySQL).
So you want the last day of the month if the last day of the month is a 4; if the day of the month is a 5 you want a date which is 1 day earlier; if the day of the month is a 3 you want a date which is 1 day later, but that's impossible (the month ends), so you really need a date six days earlier.
This means that if the daynumber difference is negative, you want it modulo seven.
You can then build this expression (#DATE is your date; I use a fake date for testing)
SET #DATE='2015-02-18';
DATE_SUB(LAST_DAY(#DATE), INTERVAL ((WEEKDAY(LAST_DAY(#DATE))+7-4))%7 DAY);
It takes the last day of the month (LASTDAY(#DATE)), then it computes its weekday, getting a number from 0 to 6. Adds seven to ensure positivity after subtracting; then subtract the desired daynumber, in this case 4 for Friday.
The result, modulo seven, is the difference (always positive) from the last day's daynumber to the wanted daynumber. Since DATE_SUB(date, 0) returns the argument date, we needn't use IF.
SET #DATE='1962-10-20';
SELECT DATE_SUB(LAST_DAY(#DATE), INTERVAL ((WEEKDAY(LAST_DAY(#DATE))+7-4))%7 DAY) AS friday;
+------------+
| friday |
+------------+
| 1962-10-26 |
+------------+
Your query then would become something like:
SELECT `name`, `date`,
DATE_SUB(LAST_DAY(`date`),
INTERVAL ((WEEKDAY(LAST_DAY(`date`))+7-4))%7 DAY) AS friday
FROM battles;
I am trying to get one week earlier then current week of the year but my sql query is returning null. here is my query
select date_sub(yearweek('2014-01-01'),INTERVAL 1 week)
what is wrong with this query
If you want to get YEARWEEK of week prior to date, you can do this:
Note: YEARWEEK results in 6-digit number, first 4 digits are week year, trailing 2 digits are week number.
SELECT YEARWEEK('2014-01-01' - INTERVAL 1 WEEK)
If you need to get a date that is one week before a given date, then:
SELECT '2014-01-01' - INTERVAL 1 WEEK
Try this
select date_sub(date('2014-01-01'),INTERVAL 1 week)
Try this:-
DATE_SUB(date('2014-01-01'), INTERVAL 7 DAY)
or
SELECT '2014-01-01' - INTERVAL 1 WEEK
The problem is that DATE_SUB takes a date as the first arguement, but year week returns yyyyww i.e. not a date. So this:
SELECT yearweek('2014-01-01');
Returns 201352, this is then implicitly casted to a date, since it is not a date the result is null. You can replicate this by doing:
SELECT DATE(yearweek('2014-01-01'));
So if you subtract a week from NULL the result is also NULL.
The fix is to subtract the week first, then get the year week:
SELECT yearweek(date_sub('2014-01-01', INTERVAL 1 WEEK));
And the result is 201351.
Are you looking for week number??? If yes then plz try this if it will work for you
Select DatePart(Week, Date add(day,-7,convert(date time,'01-jan-2014')))
Pleas let me know if you are looking for something else.
SELECT * FROM [table] WHERE WEEKOFYEAR(date) = WEEKOFYEAR(NOW()) - 1;