I need to convert a credit card expire field from MMYY to a date field I can use in a MS SQL query so I can compute when credit cards are expiring in the future. Basically, I need to go from MMYY to MM/DD/YYYY, where the day part could just be '01' (the first of the month).
I'm looking for credit cards that are expiring next month from a database. The problem I'm running into is when next month is the first month of the next year.
Here's the code I have for determining expired card:
(CAST(SUBSTRING(CCExpire,3,2) as int) + 2000 < YEAR(GETDATE()))
or
(
(CAST(SUBSTRING(CCExpire,3,2) as int) + 2000 = YEAR(GETDATE()))
AND
(CAST(SUBSTRING(CCExpire,1,2) as int) < MONTH(GETDATE()))
)
And here's the code for cards expiring this month:
(CAST(SUBSTRING(CCExpire,3,2) as int) + 2000 = YEAR(GETDATE()))
AND
(CAST(SUBSTRING(CCExpire,1,2) as int) = MONTH(GETDATE()))
Now I need code for cards expiring next month...
You're just looking for cards expiring in the next month? Why not just figure out the MMYY string of the month you're searching for, then use that in your predicate:
WHERE CCExpire = (RIGHT('00' + CAST(MONTH(DATEADD(mm, 1, GETDATE())) AS VARCHAR), 2)
+ RIGHT(CAST(YEAR(DATEADD(mm, 1, GETDATE())) AS VARCHAR), 2))
Surely it's just
(CAST(SUBSTRING(CCExpire,3,2) as int) + 2000 = YEAR(GETDATE()))
AND
(CAST(SUBSTRING(CCExpire,1,2) as int) = MONTH(GETDATE())+1)
note the +1 after the MONTH(GETDATE())
ah - just noticed your "first month of year" problem. Hang on...
You can use:
CCExpire < DATEADD(mm,GETDATE(),1) AND CCExpire > GETDATE()
that way you don't have to worry about the problem of the month wrapping into next year.
Big Edit: only just realised that you don't have a date field - you have a MMDD field. So I reckon, build up the credit card date first, maybe into a parameter to make it easier to see whats going on, using DATEADD and then use that along with the code above to evaluate.
You can convert your MMYY dates using this:
print convert(datetime, str(2000+'10')+'06'+'01')
in this example 10 is the YY and 06 is the MM, so you could use something like:
print CONVERT(datetime, str(2000+SUBSTRING(CCExpire,3,2))+SUBSTRING(CCExpire,1,2)+'01')
Surely it'd be easier to convert the CC's MMYY format to SQL server's preferred date format client-side. That'd let you store it in a normal date field, from which you could then just do normal date math:
DATEADD(month, 1, GETDATE())
would properly return the equivalent date in the next month (and adjusts so that Jan 31 + 1 month = Feb 28)
Related
I am working on a report that will send daily with the full months data minus the current day as it sends early and won't have relevant data from today.
Currently the parameter for the start as =dateadd(“m”,1,dateserial(year(Today),month(Today),0))
and the end as =DateAdd("d",-1,Today())
The problem is that this will skip the last day of each month. I want to change the start date to the first of the month from today - 1 day, but I am not sure how to do this?
I could change it to send with the current days data as well but with it sending at 8 AM the data would still be missing.
Probably least amount of code is to (1) subtract a day from today, (2) take the eomonth of the previous month, and (3) add a day.
SELECT DATEADD(DAY, 1, EOMONTH(DATEADD(DAY, -1, GETDATE()),-1));
I'm not sure what language you're doing dateserial stuff in but I'd personally do this inside SQL Server.
Also the best way to drive a report for any period is to say:
col >= start of the period
AND
col < start of *next* period
For example, for a report to cover all of last month (I realize that's not quite what you're doing, it's just a simpler example), I would say:
DECLARE #start date = DATEADD(DAY, 1, EOMONTH(GETDATE(), -2));
...
WHERE date_column >= #start
AND date_column < DATEADD(MONTH, 1, #start);
This way you don't get bitten by all of the problems that can happen with various date/time types as you try to figure out what is the end of a day or month.
For month-to-date covering yesterday and not today, I would say:
DECLARE #today date = GETDATE();
DECLARE #start date = DATEADD(DAY, 1, EOMONTH(DATEADD(DAY, -1, #today),-1));
... WHERE date_column >= #start
AND date_column < #today;
I have data prep procedure in SQL. I want to have data preparation at the end of every month
Say I want the procedure run on last day of month e.g. on 31 January 2020 it should prep data from 1 January to 31 January.
So it's kind of moving window over all months of the year. Because I need data for evaluation at the end of each month.
I tried this, however, this does not give automation. Its sort of manual running end of every month
select '2020-10-01' as beginDate_AnalysisWindow
, '2020 -01-31' as endDate_AnalysisWindow
into #AnalysisWindow --create temporary table #AnalysisWindow
I also tried the following, however, I’m not sure if it does for the whole month or just one day?
SELECT START_OF_MONTH_DATE AS beginDate_AnalysisWindow
,END_OF_MONTH_DATE AS endDate_AnalysisWindow
INTO #AnalysisWindow
FROM [dbo].[Date] WITH (NOLOCK)
WHERE DATE = DATEADD(dd, - 1, CAST(GETDATE() AS DATE))
Could someone pls help me/give me some suggestions.
Thanks in advance
If you want the last day of the current month, use eomonth():
WHERE DATE = CONVERT(date, EOMONTH(GETDATE()))
Note: This assumes that the date column has no time component. If that is the case:
WHERE CONVERT(date, DATE) = CONVERT(date, EOMONTH(GETDATE()))
SQL Server will still use an index (if available) even for this type of conversion.
EDIT:
To get the current months data, one method is:
WHERE DATE <= CONVERT(date, EOMONTH(GETDATE())) AND
DATE > CONVERT(date, EOMONTH(GETDATE(), -1))
The second argument to EOMONTH() is a months offset.
You can also try:
where getdate() <= EOMONTH(GETDATE()) AND
getdate() > DATEADD(DAY, 1, EOMONTH(GETDATE(), -1))
Instead of getdate(), you can use your date column.
I have a table with a bunch of dates (option maturity dates to be precise). I need to query this database to find the last day of a specific week that is stored in the table.
All I will be given to query this table is the year, the month and the specific week. And based on this I need to find the date that is stored in the table that matches this.
I've created the following query to find this specific date March 28 2013
SELECT M_SETNAME, M_LABEL, M_MAT FROM OM_MAT_DBF
WHERE M_SETNAME = 'IMM_OSET '
AND MONTH(M_MAT) = 3
AND YEAR(M_MAT) = 2013
AND ((DATEPART(day,M_MAT)-1)/7 + 1) = 5
Do you guys have any idea of how I can change the last condition so that March 28th will be considered the 5th week of the month and not the 4th week as it is currently doing.
You can also use DATEPART to get the number of the week (in the year), but then, you could also get the 1st of each month, and take the week too so you can have: WEEK OF MY DATE - WEEK OF FIRST DAY FOR THIS MONTH + 1.
Here you have an example...
DECLARE #Dt datetime
SELECT #Dt='03-28-2013'
SELECT DATEPART( wk, #Dt) - DATEPART( wk, Convert(Date,Convert(varchar(4),YEAR(#Dt))
+ '-' + Convert(varchar(2), MONTH(#Dt))
+ '-' + Convert(varchar(2), 1))) + 1
EDIT: Also, looking at your code, you could add the CEILING. If the result == 2.7, it means it passed the 2nd week, however, it gets rounded to 2 when it should actually be 3.
If you add the CEILING and the CONVERT to decimal should work..
SELECT MONTH(#Dt),
YEAR(#Dt),
((CEILING(Convert(decimal,DATEPART(day,#Dt)-1)/7)) + 1)
I am trying to get the last of month, and in order to that i have written the following, to calculate the no. of days between today and the last date.
select datediff(DAY,GETDATE(),dateadd(m,1,getdate()))-GETDATE()
the bold part gives me the no. of days between today and a month from today, say 30 or 31. and then I am subtracting today's date from 30 or 31, which is " -getdate() "
The output for the above query is
1786-06-06 11:44:30.540
Could you please explain what is happening in the query? I am not looking for a solution, I would like to know how is SQL-Server interpreting the query.
Thanks. :)
The bold part of the expressions does not return a date, it returns a number of days:
31
Convert that to a datetime:
SELECT CONVERT(DATETIME, 31);
This is 31 days after day 0 (1900-01-01):
1900-02-01
Now, subtract GETDATE() as an integer (41512 days after day 0):
SELECT 31 - 41512 = -41481
Now add -41481 days to day 0:
SELECT DATEADD(DAY, -41481, 0);
-- or
SELECT DATEADD(DAY, -41481, '19000101');
Or:
SELECT CONVERT(DATETIME, 31 - CONVERT(INT, GETDATE()));
Now, I strongly recommend a couple of things:
Don't use implicit date math. #date_var_or_col - 1 for example fails with new data types like DATE and DATETIME2.
Don't use shorthand like m. If you mean MONTH, just take the massive productivity hit and type out MONTH. To see why, tell me if this provides the results you expect:
SELECT DATEPART(y, GETDATE()), DATEPART(w, GETDATE());
I am subtracting today's date from 30 or 31, which is " -getdate() "
Sounds like you understand exactly what is happening, but maybe don't understand the results.
You are implicitly converting GETDATE() to a number, which represents the number of days (and fractional days) since 1/1/1900 12:00:00 AM
When you "subtract" GETDATE() (41,511 as of 8/27/2013) from 30 or 31 you get an answer of -41,480, or 41,480 days before 1/1/1900, which would be about 6/6/1786 (plus or minus a few hours for the fractional part).
i want to make a select, where the users birthday(date field) is less than 30 days.
what is the best way to to do it? i tried datediff, but i don't know how to put the year aside.
Thanks
You could just use DATEPART function with dayofyear datepart value.
EDIT: honestly, there is a boundary issue in my previous answer (many thanks to Damien): e.g. 2010-12-25 and 2011-01-07 => the difference should be less then 30 days, but DATEPART(dayofyear, #date) - DATEPART(dayofyear, [Birthday]) < 30 condition would skip this record. So I added an additional contition to my answer:
DATEPART(dy, #d) - DATEPART(dy, [Birthday]) < 30 OR
(
DATEPART(mm, #d) = 12 AND
DATEPART(dy, DATEADD(m, 1, #d)) - DATEPART(dy, DATEADD(m, 1, [Birthday])) < 30
)
it adds one month to the each date in the case when the month part of the first date is December and compares the difference.
A common way is to compose a formatted date, as text, and replace the year with the current year; and parse back into a date. Apply datediff on that.
If you find out datediff returns something negative thus the birthday of this year is in the past, add 1 year, and try again. This is for the time period around New Year.
SELECT *
FROM dbo.CheckBirthDay
WHERE (CASE WHEN YEAR(BirthDay) <= YEAR(CURRENT_TIMESTAMP) THEN DATEDIFF(DD,BirthDay,CURRENT_TIMESTAMP) END < 30 )