How can I combine fixed month and day with sql year function? - sql

I want to compose a date in T-SQL with a fixed day and month (always the last day and month of the year), the year must be variable.
the day is always: 31
the month is always: 12
the year is variable, let's say 2014
The format would be like 12-31-2014 or 12-31-2015.
I have the YEAR function in mind:
select '12'+YEAR(getdate())-1
but this results in 2014+12=2026.
How can I achieve this with T-SQL?

SQL Server has the DATEFROMPARTS function for this purpose:
DECLARE #date datetime = DATEFROMPARTS( 2014, 12, 31 )
Documented here: https://msdn.microsoft.com/en-us/library/hh213228.aspx

The problem you are running into is that YEAR() returns a number so the server is adding instead of concatenating. So, if you want to do it with concatenation, you'll need to force that number back into a CHAR(), and then recast the whole concatenated mess back into a DATE (assuming you want a date type returned):
select CAST('12-31-'+CAST(YEAR(getdate())-1 AS CHAR(4)) as DATE)
That being said #Dai's answer using select DATEFROMPARTS(YEAR(getdate())-1, 12, 31) is a little bit easier on the eyes, and probably the CPU.

Related

SQL - How to get transaction count month to date

I am trying to get transaction count month to date. For now I am providing date between from_date and to_date.
How can I get results for a particular month in month to date ?
You don't mention what SQL your using, but if its SQL Server then it has a built in function DatePart description I'd expect most of the major SQL dialects to have something similar.
So your where clause would be something like where datepart(mm, to_date) = 4 (for April)
If your version SQL doesn't have the date functions, then you can fallback to the cruder string manipulation. Assuming your date is yyyymmdd, then you could use a sub string function to pull out the mm part, convert that to a integer and perform your comparison.

LEFT Function in SQL Server returns no results

I am trying to place data corresponding to a certain month into a temp table from an SQL database.
DROP TABLE
#ComPAIR_Alliance_Table
SELECT
IMOno
,period
,[service]
,alliances
INTO
#ComPAIR_Alliance_Table
FROM
com_COMPAIR.dbo.Data_BlueWaterCapacity_US_2
WHERE
LEFT(period, 7) = '2015-03'
SELECT
*
FROM #ComPAIR_Alliance_Table
The period field is in the following format: 2015-03-29 00:00:00.000
However, my code just returns an empty temp table with the right column names but no rows (even though I know for sure rows with that date exist in my table). I have already made sure that the period column is indeed a string by using is.numeric.
Could someone please help me out with what the problem could be?
Thanks!
If it is a date/datetime/datetime2 then you can compare it with 2015-03 like:
WHERE period >= '2015-03-01'
AND preiod < DATEADD(MONTH, 1, '2015-03-01')
In case there is confusion:
The above will match all March 2015 dates such as 2015-03-31, 2015-03-31 23:59:59 and 2015-03-31 23:59:59.9999999
The above is sargable: the DATEADD part does not depend on the table rows
Guessing Period is a date. If it is, stop treating it like a varchar, it isn't one. If you want values from March 2015 then do:
WHERE period >= '20150301'
AND period < '20150401'
LEFT is doing some weird stuff, because LEFT causes an implicit cast to String from Date. You can see this question for more information, but you're getting exactly what you told SQL to get - a join on rows where the left 7 characters of period equal '2015-03' which will not happen, since you're liking comparing against something like 'Jan 01'
The LEFT function needs to implicitly convert your datetime column to a varchar value to do it's work. SQL Server is choosing the varchar format of the date based on it's internationalization settings. On my server, its Mar 29 2015 12:00AM, and LEFT yields Mar 29. That's why it's not equal to 2015-03.
You should treat your column as a datetime and then perform the comparison using a valid datetime comparison, like this :
WHERE period BETWEEN '1/1/2015' AND '1/31/2015'
the date is stored as a date type. You may want to try
where convert(varchar(20), period,121)
which would convert it to string...

Format date where the position of the parts is variable

We have a file that needs to be imported that has dates in it. The dates are in a format that I have not seen before and the day part can vary in length (but not the month or year seemingly) and position based on wether the number is double digit or not, i.e.
Dates:
13082014 is 13th February 2014
9092013 is 9th September 2013
The current script tries to substring the parts out, but fails on the second one as there is not enough data. I could write an if or case to check the length, but is there a SQL format that can be used to reliably import this data?
To clarify this is MSSQL and the date format is ddmmyyyy or dmmyyyy
One of the simple way is using STUFF.
example:
select STUFF(STUFF('13082014 ',3,0,'/'),6,0,'/');
//result: 13/08/2014
Good luck.
LPAD a zero when it is missing so to always get an eight character date string. Here is an example with Oracle, other DBMS may have other string and date functions to achieve the same.
select to_date(datestring, 'ddmmyyyy')
from
(
select lpad('13082014', 8, '0') as datestring from dual
union all
select lpad('9092013', 8, '0') as datestring from dual
);
Result:
13.08.2014
09.09.2013
you can convert the dates to a relevant date format then import data(based on the dateformat change the logic).
something like this :
select Convert(varchar(10),CONVERT(date,YourDateColumn,106),103)

What is being compared? GETDATE() - TSQL

Hello I am wondering what gets compared or what the representation of the
GETDATE() > 1
is in the following line of T-SQL code below.
WHERE DATEDIFF(dd, CDF_AS_OFDATE, GETDATE()) > 1 )
What would happen if I decided to use 100 instead of 1? (I tried it, simply returned a smaller result set).
It's comparing the difference in days between CDF_AS_OFDATE and the current date, to see if it's more than 1 day. If you change it to those that have more than 100 days difference, it would most likely be a much smaller result set.
(You can determine it's in days by noticing that it's using DATEDIFF() with the dd parameter, which indicates you want the difference in days.)
it check if there was more than 1 day difference between the two date (then vs now)
SQL Server DATEDIFF() Function
The DATEDIFF() function returns the time between two dates.
Syntax
DATEDIFF(datepart,startdate,enddate)
Where startdate and enddate are valid date expressions and datepart can be one of the following:
day dd, d
Example
Now we want to get the number of days between two dates.
We use the following SELECT statement:
SELECT DATEDIFF(day,'2008-06-05','2008-08-05') AS DiffDate
Result:
DiffDate
61
The answer is in the DATEDIFF part of the WHERE clause.
It actually evaluates only those rows where the value of CDF_AS_OFDATE at least 1 day different from the current system date.
Where to start...
In your first example...
where getdate() > 1
First getdate() returns the current date and time-of-day as a datetime value. If you read the documentation, you'll discover that (1) there is no implicit conversion from datetime to int, but there is an implicit conversion from int to datetime. That means the expression is pretty much identical to
where getdate() > convert(datetime,1)
The epoch (zero point) of the SQL Server calendar is 1900-01-01 00:00:00.000, which is what you get if you say convert(datetime,0) or convert(datetime,''). When you convert an int value to a datetime value, the integer value is taken to indicate an offset in days since the epoch. The conversion is performed by adding that many days to the epoch to get the resulting datetime value: convert(datetime,1) thus yields the datetime value 1900-01-02 00:00:00.000 and your expression is thus the equivalent of
where getdate() > '1900-01-02 00:00:00.000'
which expression will always be true unless you've seriously mucked with your systems clock.
In your second example...
where datediff( dd , CDF_AS_OF_DATE , getdate() ) > 1
getdate() as noted earlier gives you the current date and time-of-day.
datediff() returns the delta between two datetime values in the requested units of time. If you want to be pedantic about things (and I do), depending on the unit requested, the resulting value is not necessarily correct (depend on your definition of "correct"): what you get is the count of unit boundaries between the two datetime values. So even though exactly one second separates the two datetime values in the expression below,
datediff(dd,'Dec 31, 2013 23:59:59','Jan 1, 2014 00:00:00') returns 1 indicating a delta of 1 day, whilst
datediff(year,'Dec 31, 2013 23:59:59','Jan 1, 2014, 00:00:00') likewise returns1` indicating a delta of 1 year.
So your where clause is restricting the result set to rows where the delta (in days) from the as-of date to the current date/time is greater than 1.

Storing just Month and Year in SQL Server 2008?

Is it possible to save the month/year in SQL Server 2008 with a regular datetime? I don't need a time stamp and the column is going to store unique mo/yr combinations (i.e. 10-11, 11-11, 12-11, etc,.).
Any recommendations?
Without knowing the intended use, it is not possible to advise correctly. However, storing month and year is easily done in at least three ways:
use a date field, but always store into it the first day of the month at midnight; then always custom format the date field for display
add integer year and month fields, and populate them by splitting a date
add an integer field where you encode it as year * 100 + month or some other useful scheme
Sql Server will store the datetime data in its entirety (year-month-day hour:min:sec.milliSec) no matter what.
When you store your dates, you can make the day the 1st of the month. Just format the dates how you want when you do your queries.
http://www.sql-server-helper.com/tips/date-formats.aspx
From SQLServer 2008 and onwards:
Save as a Date column and add the following check constraint to make sure the value is always the first of the month:
datepart(month, MyDate)<>datepart(month,dateadd(day, -1, MyDate))
You cant only store year and month in a DateTime column. Well, what you can do is default the rest of the values. ie: 2011.10.1.1 , 2011.11.1.1 like that.
Or you can store it as string.
SELECT RIGHT(CONVERT(VARCHAR(10), GETDATE(), 105), 7) AS [MM-YYYY]
You should try this