Expiry DateEnd
None 2000-06-29 00:00:00.000
None 2000-06-29 00:00:00.000
september 2013 2013-06-29 00:00:00.000
January 2012 2013-06-29 00:00:00.000
May 2020 2013-06-29 00:00:00.000
2013-06-29 00:00:00.000 2013-06-29 00:00:00.000
From two column I want pick all dates except May 2020 rows, due to future date.
this is what I have so far
DECLARE #YearFlag datetime
SET #YearFlag = DATEADD(yy,-5,GETDATE())
SELECT *
FROM #Table
WHERE (DateEnd IS NULL OR DateEnd = '' OR DateEnd <= #YearFlag)
OR (CHARINDEX(Convert(varchar, YEAR(GETDATE())),Expiry) > 0)
was using below one to pick January 2012 row but getting error
OR (Expiry != 'none' AND Expiry <= GETDATE())
I assume you want to exclude future dates from your select, so you can use something like this.
(also, please specify RDBMS because the GETDATE() function might not be available in the one you're using)
SELECT Expiry,
DateEnd
FROM YOUR_TABLE
WHERE Expiry <> 'none'
AND convert(INT, substring(expiry, charindex(' ', expiry, 0), len(expiry))) < YEAR(GETDATE())
AND CASE LOWER(substring(expiry, 0, charindex(' ', expiry, 0)))
WHEN 'january' THEN 1
WHEN 'february' THEN 2
WHEN 'march' THEN 3
WHEN 'april' THEN 4
WHEN 'may' THEN 5
WHEN 'june' THEN 6
WHEN 'july' THEN 7
WHEN 'august' THEN 8
WHEN 'september' THEN 9
WHEN 'october' THEN 10
WHEN 'november' THEN 11
ELSE 12
END < MONTH(GETDATE())
Here is a SQLFiddle with how the code works.
Related
I need to find next final pay period under few conditions. The maturity is 3 months, but when the last payday is till the 3st business day of the current month. Оtherwise is the maturity 4 months. And Saturday and Sunday are not working days. For example: now in August 2019 are 3.08 and 4.08 not working day and when the customer pay the tax till 5.08(Monday - this is the 3st business day for a August) the next payday period is till end of Oktober 2019. Otherwise when the day is 6.08 is the period till end of November
IF #Schema = '1000'
BEGIN
SET #PayPeriod = 3
IF #Payday < DATEADD(DAY, CASE (DATEPART(WEEKDAY, DATEADD(MONTH, DATEDIFF(MONTH, 0, #Payday), 0)) + ##DATEFIRST) % 7
WHEN 6 THEN 2
WHEN 7 THEN 1 ELSE 0 END,
DATEADD(MONTH, DATEDIFF(MONTH, 0, Payday), 3))
SET #PayPeriod = EOMONTH(#Payday, #PayPeriod-1)
ELSE SET #PayPeriod = EOMONTH(#Payday, #PayPeriod)
END
And here is the result. After 06.08.2019 must be the payperiod end of November
2019-08-01 2019-10-31
2019-08-02 2019-10-31
2019-08-03 2019-10-31
2019-08-04 2019-11-30
2019-08-05 2019-11-30 here is the problem!
2019-08-06 2019-11-30
This should work for you:
declare #payday as datetime = '20190602'
;with cte as (
select datefromparts(year(#payday), month(#payday), 1) as monthday
union all
select dateadd(day, 1, monthday)
from cte
where day(monthday) < 10
)
select
case
when count(*) <= 3 then eomonth(#payday, 3)
else eomonth(#payday, 4)
end as MaturityEnd
from cte
where datepart(weekday, monthday) not in (7, 1)
and monthday <= #payday
Here we generate first couple of dates for the same month as in payment date and count business days smaller than payment date. Maturity end date is calculated based on the count of days.
It is not totally clear what you want from your question. I believe what you want is:
Give a date ##DATEFIRST find a date of maturity
3 months later unless
that date falls in the first 3 business days of a month than then
4 months later
Is that correct?
Also what does EOMONTH do? The use of it in your example does not seem to make sense compared to the stated requirements.
I'm looking at changing a specific date to a different date in a case statement, however, I only want it to apply to a day, month and time.
For example, I want to get the case statement to change any date which falls on 31/12 # 23:59:00 to 01/01 # 00:00:00 but unless I write the case to include each year for the next 40 years to cover myself, I've not been able to resolve this.
I am writing this from the UK with date format being dd/mm/yyyy (above example is 31st December and 1st January).
The format of the datetime field in the database is 'datetime': 2019-07-01 13:14:47).
I can't tell if you want the return type to be a date or datetime. If a date, you can do:
(case when year(dateadd(minute, 1, datecol)) <> year(datecol)
then datefromparts(year(datecol) + 1, month(datecol), day(datecol))
else cast(datecol as date)
end)
The logic would be similar for a datetime, assuming datecol is already a datetime:
(case when year(dateadd(minute, 1, datecol)) <> year(datecol)
then datefromparts(year(datecol) + 1, month(datecol), day(datecol))
else datecol
end)
If I understand correctly you want to round the dates inside last minute of year into the next year. You can do this:
SELECT datecol, CASE
WHEN MONTH(datecol) = 12 AND DAY(datecol) = 31 AND CAST(datecol AS TIME(3)) >= '23:59:00' THEN CAST(DATEADD(MINUTE, 1, datecol) AS DATE)
ELSE datecol
END
FROM (VALUES
(CAST('2018-12-31 23:58:59.997' AS DATETIME)),
(CAST('2018-12-31 23:59:00.000' AS DATETIME)),
(CAST('2018-12-31 23:59:59.997' AS DATETIME)),
(CAST('2019-01-01 00:00:00.000' AS DATETIME))
) AS v(datecol)
Result:
2018-12-31 23:58:59.997 2018-12-31 23:58:59.997
2018-12-31 23:59:00.000 2019-01-01 00:00:00.000
2018-12-31 23:59:59.997 2019-01-01 00:00:00.000
2019-01-01 00:00:00.000 2019-01-01 00:00:00.000
I am looking for some T-SQL code that should pick the date which is "One Year back from current date (at the same time last Sunday in the month of January)".
For example:
Current day expected result
2017-02-05 2016-01-31
2017-01-05 2015-01-25
2018-02-19 2017-01-29
2018-01-19 2016-01-31
2019-02-28 2018-01-28
Please note: The year starts from last Sunday in January
I have some T-SQL code which is being used in SQL Server 2014:
select
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
The above code picks the date for current year's (last Sunday in January month). But I want T-SQL code to pick last year's (last Sunday's date in January month) date.
In detail - I want T-SQL code to produce expected result from below table
Current day T-SQL code answer expected result
2017-02-05 2017-01-29 2016-01-31
2017-01-05 2016-01-31 2015-01-25
2018-02-19 2018-01-28 2017-01-29
2018-01-19 2017-01-29 2016-01-31
2019-02-28 2019-01-27 2018-01-28
Any help please.
The best thing for this question is a numbers and date table. This answer shows you how to create one. Such a table is very handsome in many situations...
If I understand this correctly, you want the last Sunday in January of the previous year in all cases? Try this:
DECLARE #dummy TABLE(ID INT IDENTITY,YourDate DATE);
INSERT INTO #dummy VALUES
('2017-02-05'),('2017-01-05'),('2018-02-19'),('2018-01-19'),('2019-02-28');
WITH Years AS
(
SELECT * FROM (VALUES(2010),(2011),(2012),(2013),(2014),(2015),(2016),(2017),(2018),(2019),(2020)) AS t(Yr)
)
,LastSundays AS
(
SELECT Yr AS TheYear
,DATEADD(DAY,(DATEPART(WEEKDAY,LastOfJanuary) % 7)*(-1),LastOfJanuary) AS LastSundayOfJanuary
FROM Years
CROSS APPLY(SELECT CAST(CAST(Yr AS VARCHAR(4)) + '0131' AS DATE)) AS t(LastOfJanuary)
)
SELECT *
FROM #dummy AS d
INNER JOIN LastSundays AS ls ON YEAR(DATEADD(YEAR,-1,d.YourDate))=ls.TheYear;
The result (I do not understand row 2 and 4 completely...)
ID YourDate TheYear LastSundayOfJanuary
1 2017-02-05 2016 2016-01-31
2 2017-01-05 2016 2016-01-31 <--Your sample data is different...
3 2018-02-19 2017 2017-01-29
4 2018-01-19 2017 2017-01-29 <--Your sample data is different...
5 2019-02-28 2018 2018-01-28
Hint You might need to introduce ##DATEFIRST into your calculations...
Here is a way to do it without a date table (which is still a good idea BTW). Tested on all your inputs and it delivers the correct output each time. Obviously you would refactor this a bit as it's longwinded, just to show each step.
/* The input date. */
DECLARE
#input DATE = '2019-02-28';
/* The input date less one year. */
DECLARE
#date_minus_one_year DATE = DATEADD(yy,-1,#input);
/* The year part of the input date less one year. */
DECLARE
#year_date_part INT = DATEPART(yy,#date_minus_one_year);
/* 31 Jan of the previous year. */
DECLARE
#prev_year_jan_eom DATE = CAST(CAST(#year_date_part AS VARCHAR(4))+'-01-31' AS DATE);
/* What day of the week is 31 Jan of the previous year? */
DECLARE
#previous_eom_dw_part INT = DATEPART(dw,#prev_year_jan_eom);
/* Offest 31 Jan to the previous Sunday, won't change if the 31st is itself a Sunday. */
DECLARE
#output DATE = DATEADD(dd,1 - #previous_eom_dw_part,#prev_year_jan_eom);
/* Input and output */
SELECT
#input input
,#output [output];
I didn't think of a way to do it without the conditional in a case. It also uses the trick of casting a numeric year value to a January 1st date.
select case
when
datepart(dayofyear, dt) >
31 - datepart(weekday, dateadd(day, 30, cast(year(dt) as varchar(4))))
then
dateadd(day,
31 - datepart(weekday, dateadd(day, 30, cast(year(dt) as varchar(4)))),
cast(year(dt) as varchar(4))
)
else
dateadd(day,
31 - datepart(weekday, dateadd(day, 30, cast(year(dt) - 1 as varchar(4)))),
cast(year(dt) - 1 as varchar(4))
)
end
from (values
('20100201'), ('20110301'), ('20120401'),
('20130501'), ('20140601'), ('20150701'),
('20160801'), ('20170901'), ('20181001')
) t(dt)
Just for fun (untested)
select
dateadd(week,
-52 * ceil(sign(datediff(day, dt, hs)) + 0.5),
js
)
from
(select <date> dt) as t
cross apply
(
select 31 - datepart(weekday,
datefromparts(year(dt), 1, 31) as js
) t2;
SELECT
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
I want to get month value using week no.
I have week numbers stored in a table with year value.
How to query database to get month value using that week value.
I am using SQL
You can try this:
SELECT DATEPART(m,DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + CAST(t.year as VARCHAR(4))) + (t.week-1), 6))
It depends on how you're classing your week numbers, For example, if we assume that week numbers start on a Monday then we'd have to say that week 1 in 2016 actually started on Monday 28th of December 2015 and finished on Sunday 3rd January 2016. If this is how your week numbers are set up then you can use the method below
Sample Data;
CREATE TABLE #DateTable (WeekNum int, YearNum int)
INSERT INTO #DateTable (WeekNum, YearNum)
VALUES
(1,2016)
,(2,2016)
,(3,2016)
,(4,2016)
,(5,2016)
,(6,2016)
,(7,2016)
We will then cast the week and year into a date, then convert this to a month;
SELECT
WeekNum
,YearNum
,DATEADD(wk, DATEDIFF(wk, 7, '1/1/' + CONVERT(varchar(4),YearNum)) + (WeekNum-1), 7) AS WeekStart
,DATEPART(mm,DATEADD(wk, DATEDIFF(wk, 7, '1/1/' + CONVERT(varchar(4),YearNum)) + (WeekNum-1), 7)) MonthNum
(Edit: updated as source is int)
Gives these results;
WeekNum YearNum WeekStart MonthNum
1 2016 2015-12-28 00:00:00.000 12
2 2016 2016-01-04 00:00:00.000 1
3 2016 2016-01-11 00:00:00.000 1
4 2016 2016-01-18 00:00:00.000 1
5 2016 2016-01-25 00:00:00.000 1
6 2016 2016-02-01 00:00:00.000 2
7 2016 2016-02-08 00:00:00.000 2
You can't go from week number to month because weeks can occur in two different months. For example the 31st Jan 2016 and 1st Feb 2016 are both in week 6.
SELECT DATEPART(WEEK, '2016-01-31')
SELECT DATEPART(WEEK, '2016-02-01')
You can try the query below:
SELECT
[Week],
[Year],
'Output-Month' = MONTH(DATEADD(WEEK, [Week], DATEADD(WEEK, DATEDIFF(WEEK, '19050101', '01/01/' + CAST([Year] AS VARCHAR(4))), '19050101')))
FROM YourTable
1st is to get the 1st day of the year using this:
DATEADD(WEEK, DATEDIFF(WEEK, '19050101', '01/01/' + CAST([Year] AS VARCHAR(4))), '19050101')
2nd is to add your number of week using this:
DATEADD(WEEK, [Week], 'From 1st result')
Last is getting the number of Month using the MONTH function.
I need the records order by month on school year, ex
August
September
October
November
December
January
February
March
April
May
June
To get that order i found this order by but is returning the records with numbers and i need the name of the month. How can i get the name of the month without affecting the order?
SELECT CASE
When G.MO = 8 then 'August'
When G.MO = 9 then 'September'
When G.MO = 10 then 'October'
When G.MO = 11 then 'November'
When G.MO = 12 then 'December'
When G.MO = 1 then 'January'
When G.MO = 2 then 'February'
When G.MO = 3 then 'March'
When G.MO = 4 then 'April'
When G.MO = 5 then 'May'
When G.MO = 6 then 'June'
When G.MO = 7 then 'July'
end as [Month]
,...
from TABLE
group by [Month]
order by convert(nvarchar,(CASE WHEN CAST(LEFT(G.MO, 2) AS int) >= 8 THEN CAST(LEFT(G.MO, 2) AS int) - 8 ELSE CAST(LEFT(G.MO, 2) AS int) + 4 END
Usual way to rotate a sequence is mod function.
ordre by (g.mod+4)%12
--(8+4)%12=0
--(9+4)%12=1
--...
--(7+4)%12=11
Just use a simple comparison to put the months after august first:
order by (case when g.mo >= 8 then 1 else 2 end),
g.mo
Also, you can simplify the naming by doing:
select datename(month, cast(replace('2000-#mon-01', '#mon', g.mo) as date))
The cast() is actually not necessary, but I much prefer explicit conversion to implicit conversion.