Comparing Dates in a specific format in SQL Server - sql

I have a column called "Mon-YY" (varchar(n) data type) in one of my tables which has values like:
Aug-12
Sep-12
Oct-12
Nov-12
Dec-12
Jan-13
Feb-13
Mar-13
Apr-13
May-13
Jun-13
I want to compare these values and retrieve the records from the table based on the date range specified.
I am assuming I'd need to convert the above values into DATE format. But I'm not sure then how do I keep track of days too.

You can use the DATEPART function, but you need to do it on a full date:
SELECT DATEPART(MM, 'Aug-12') --> error
SELECT DATEPART(MM', 01-Aug-12') --> 8
So try something like this:
SELECT
DATEPART(MM, CONCAT('01-', [Mon-YY])) AS TheMonth,
DATEPART(YYYY, CONCAT('01-', [Mon-YY])) AS TheYear
FROM myTable
ORDER BY TheYear, TheMonth

SELECT CONVERT (date, REPLACE (MyColumn, '-', ' 01 '))
FROM MyTable
Something like this should give you a date. It will always be the first of the month. You can use the expression in a WHERE clause with <, >, or BETWEEN. I don't know why you would need to keep track of them.

I used cast
-- example table and data
DECLARE #table table
(
[Mon-YY] varchar(20)
)
insert into #table values ('Aug-12')
insert into #table values ('Sep-12')
insert into #table values ('Oct-12')
insert into #table values ('Nov-12')
insert into #table values ('Dec-12')
insert into #table values ('Jan-13')
insert into #table values ('Feb-13')
insert into #table values ('Mar-13')
insert into #table values ('Apr-13')
insert into #table values ('May-13')
insert into #table values ('Jun-13')
select cast('01-' + [Mon-YY] as Date)
from #table

To convert these values to date you should use:
SELECT CONVERT(VARCHAR(20), '01 ' + [Mon-YY], 6) as BeginOfInterval
To get the last day of a month, you should use (look here):
SELECT DATEADD(s,-1,DATEADD(mm,
DATEDIFF(m,0,CONVERT(VARCHAR(20), '01 ' + [Mon-YY], 6))+1,0)) as EndOfInterval
Then you could use this two queries to get the first and last dates of interval.

A solution is to transform your column in something easier to sort like a number.
Bellow I transform the column in the full year followed by the month (numeric index 1 to 12) but this is used only in order by clause.
select *
from theTable
--where ???
order by case when right([mon-yy],2) <= 70 then '19' else '20' end +
right([mon-yy],2) +
case left([mon-yy],3)
when 'Jan' then '01'
when 'Feb' then '02'
when 'Mar' then '03'
when 'Apr' then '04'
when 'May' then '05'
when 'Jun' then '06'
when 'Jul' then '07'
when 'Aug' then '08'
when 'Sep' then '09'
when 'Oct' then '10'
when 'Nov' then '11'
when 'Dec' then '12'
end

Related

Convert Quarter + Year to a date

I have two fields I need to combine and convert to a date. These two fields are i) Quarter &
ii) Year
For example Q2 2017
01/04/2018
I don't have a field for the day so I just want to keep it to the first of the month.
Please could someone help with the SQL. I need to add to a select statement.
In Microsoft SQL Server you can do this as followed:
First I create a date as varchar which I then convert to the Date datatype. After this I format it to the desired format. I use a CASE Clause to get the correct month by the quarter.
SELECT FORMAT(CONVERT(DATE,CAST([Year] AS VARCHAR(4))+'-'+
CAST(CASE
WHEN [Quarter] = 'Q1' THEN '01'
WHEN [Quarter] = 'Q2' THEN '04'
WHEN [Quarter] = 'Q3' THEN '07'
WHEN [Quarter] = 'Q4' THEN '10' END AS VARCHAR(2))+'-'+
CAST('01' AS VARCHAR(2))), 'dd-MM-yyyy', 'en-us')
from dates
If you are using SQL SERVER , then you can try something like this:
SELECT
CONCAT(Quarter,
CONVERT(date, DATEADD(MONTH, DATEDIFF(MONTH, 0, year), 0))) AS StartOfMonth
FROM Table1;
If you need some space in between Quarter and Year then, add ' '.
SELECT
CONCAT(Quarter,' ',
CONVERT(date, DATEADD(MONTH, DATEDIFF(MONTH, 0, year), 0))) AS StartOfMonth
FROM Table1;

Return records less than date

I have a table where 2 columns are called Month and Year and are both INT. I need to return all the records that are less than the date provided.
So if I pass the following parameters #Month = 8 and #Year = 2017, I would like to return all records before August 2017. What is the best way to achieve this?
SELECT * FROM testTable
WHERE year <= #Year AND
month < #Month
is my current SQL. This won't work if I need to display the record that is November 2014
Compare them as dates. Like this:
SELECT * FROM testTable
WHERE DATEFROMPARTS(year, month, 1) <= DATEFROMPARTS(#Year, #Month, 1)
Pass The Parameter as Date. Like
DECLARE #MyDate DATE = '08-01-2014'
Now you can go for either of the below
SELECT
*
FROM YourTable
WHERE CAST(ConCAT([Monnth],'-01-',[Year]) AS DATE) = #MyDate
Or
SELECT
*
FROM YourTable
WHERE [Year] = YEAR(#MyDate)
AND [Month] = MONTH(#MyDate)
You can use DATEPART function of SQL Server
SELECT * FROM testTable
WHERE YEAR<= DATEPART(yy,yourdate) AND
MONTH < DATEPART(mm,yourdate)
It would be better to convert data types and query further.
DECLARE #testtable TABLE (id INT identity(1, 1), name VARCHAR(100), year INT, month INT)
INSERT INTO #testtable (name, year, month)
SELECT 'me', '2014', 10
UNION
SELECT 'you', '2017', 08
UNION
SELECT 'us', '2015', 10
UNION
SELECT 'Him', '2017', 10
UNION
SELECT 'Her', '2018', 1
SELECT *
FROM #testtable
WHERE CONCAT (year, '-', right('00' + cast(Month AS VARCHAR(2)), 2), '-', '01')
< = '2017-08-01'

Convert YYYYMM to MMMYY

I have a period 201604 (nvarchar). Is there a way that I can convert 201604 to APR16?
Use the DATENAME & SUBSTRING functions, like this:
declare #str nvarchar(50) = '201604'
select UPPER(left(datename(mm,cast(#str+'01' as date)),3))+substring(#str,3,2) --APR16
It is a bit ugly, but you can't use any of the built-in date formatting stuff as is. Feel free to swap out the case statement for a join if you have a month names table, etc.:
DECLARE #exampleVal NVARCHAR(6) = '201604';
SELECT CASE SUBSTRING(#exampleVal, 5, 2)
WHEN '01' THEN 'JAN'
WHEN '02' THEN 'FEB'
WHEN '03' THEN 'MAR'
WHEN '04' THEN 'APR'
WHEN '05' THEN 'MAY'
WHEN '06' THEN 'JUN'
WHEN '07' THEN 'JUL'
WHEN '08' THEN 'AUG'
WHEN '09' THEN 'SEP'
WHEN '10' THEN 'OCT'
WHEN '11' THEN 'NOV'
WHEN '12' THEN 'DEC'
END +
SUBSTRING(#exampleVal, 3, 2)
Try this:
Add '01' (as first day of month), so convert your varchar to datetime and get the datename of the month:
declare #myperiod nvarchar(10)
SET #myperiod = '201604'
SET #myperiod = #myperiod + '01'
SELECT UPPER(SUBSTRING(DATENAME(month, CONVERT(datetime, #myperiod)), 1, 3)) +
SUBSTRING(CONVERT(varchar, DATEPART(year, CONVERT(datetime, #myperiod))), 3, 4)
Add 01 at the last, so that it changes to a valid date format. Then use the datename function:
DECLARE #STRING VARCHAR(10)='201604'
SELECT DATENAME(MONTH,#STRING+'01') +' '+SUBSTRING(#STRING,3,2)
Output:
April 16
In two lines:
declare #napis varchar(6)='201506'
SELECT UPPER(LEFT(DATENAME(month, #napis+'01'),3)) + SubString(#napis,3,2)
Another option is by using Format() and DateFromParts(). This will work in SQL Server 2012 or newer versions:
Declare #Period NVarchar (6) = N'201604'
Declare #Format NVarchar (5) = N'MMMyy'
Select Upper(Format(DateFromParts(Left(#Period, 4), Right(#Period, 2), 1), #Format))
APR16
Use simple this
declare #test nvarchar(max) = '201604'
select left(DATENAME(month, #test +'01'),3) + SubString(#napis,3,2)
Another way:
DECLARE #Date varchar(6) = '201604'
SELECT REPLACE(SUBSTRING(CONVERT(char(9), CAST(#Date +'01' as Date), 6), 4, 7), ' ', '')
Try this one..
DECLARE #DATE NVARCHAR(6) = '201604'
SELECT datename(MONTH,CONVERT(DATE,CONVERT(DATE,LEFT(#DATE,4)+'.'+RIGHT(#DATE,2)+'.01',102),102))

Date in MON-YYYY format to Text format

How do I convert date format field to MON-YYYY format.
I have date 12-06-2014 and I want to compare it with JUN-2014.
Here is a link that explains everything about date format:
Date Format
Your solution is probably the following (MySQL version):
UPPER(DATE_FORMAT(yourDate, '%b-%Y'))
And for SQL Server:
UPPER(SUBSTRING(DATENAME(MONTH, yourDate), 1, 3) + '-' + CAST(DATEPART(YEAR, yourDate) AS VARCHAR(4)))
Hope this will help you
The SQL Server syntax is:
UPPER(FORMAT(yourDate, 'MMM-yyyy'))
SQL supports a number of different date formats, but does not support non-numeric based date formats. I would strongly suggest finding a method which uses one of these formats as suggested the Microsoft SQL documentation.
Alternatively, if it is absolutely necessary that you use this format, then the following code can change any date format into the format you have requested.
declare #date date = '2014-01-01'
select
case when DATEPART(mm,#date) = 1 then 'JAN'
when DATEPART(mm,#date) = 2 then 'FEB'
when DATEPART(mm,#date) = 3 then 'MAR'
when DATEPART(mm,#date) = 4 then 'APR'
when DATEPART(mm,#date) = 5 then 'MAY'
when DATEPART(mm,#date) = 6 then 'JUN'
when DATEPART(mm,#date) = 7 then 'JUL'
when DATEPART(mm,#date) = 8 then 'AUG'
when DATEPART(mm,#date) = 9 then 'SEP'
when DATEPART(mm,#date) = 10 then 'OCT'
when DATEPART(mm,#date) = 11 then 'NOV'
when DATEPART(mm,#date) = 12 then 'DEC' end
+ '-'
+ CONVERT(char(4),DATEPART(yy,#date)) as new_format
You could use something like the following to format the date and compare (SQL Fiddle):
SELECT *
FROM
(
SELECT
CONCAT(
CONVERT(CHAR(3), CONVERT(DATE, MyDateField, 105), 0),
'-',
DATEPART(YYYY, CONVERT(DATE, MyDateField, 105))
) AS DF
FROM MyTable
) m
WHERE m.DF = 'JUN-2014';
You can use below for convert date formate.
select left(datename(mm,[Date]),3)
+'-' + cast( DATEPART(YYYY,[date]) as nvarchar(50))
from ArtistCalendar
You can use the DATENAME() function to get the name for a given month, which can be abbreviated like so:
SELECT LEFT(DATENAME(mm, GETDATE()),3) -- Output: 'Sep'
You can append the year using:
SELECT YEAR(GETDATE())
This should have to be converted to a string value to enable comparison with your supplied value. So you can do this:
SELECT LEFT(DATENAME(mm, GETDATE()),3) + '-'
+ CAST(YEAR(GETDATE()) AS NVARCHAR(4)) AS InputDate -- Output: Sep-2014
To check equality of a supplied value, e.g. Sep-2014:
SELECT LEFT(DATENAME(mm, GETDATE()),3) + '-'
+ CAST(YEAR(GETDATE()) AS NVARCHAR(4)) AS InputDate,
GETDATE() as FullDate,
CASE WHEN LEFT(DATENAME(mm, getdate()),3) + '-'
+ CAST(YEAR(GETDATE()) as nvarchar(4)) = 'SEP-2014'
THEN 'True'
ELSE 'False'
END as Equality
Ouptut
InputDate FullDate Equality
----------------------------------------------
Sep-2014 2014-09-15 14:35:57.427 True
To use with your table:
DECLARE #compareDate AS NVARCHAR(10)
SET #compareDate = 'Jan-2014' -- set this
SELECT LEFT(DATENAME(mm, [YOUR_COL]),3) + '-'
+ CAST(YEAR([YOUR_COL]) AS NVARCHAR(4)) AS InputDate,
[YOUR_COL]as FullDate,
CASE WHEN LEFT(DATENAME(mm, [YOUR_COL]),3) + '-'
+ CAST(YEAR([YOUR_COL]) as nvarchar(4)) = #compareDate
THEN 'True'
ELSE 'False'
END as Equality
From [YOUR_TABLE]
Just replace [YOUR_COL] with your date column and [YOUR_TABLE] with the table that holds the data column.
In Oracle SQL
You can do something like this
TO_CHAR(column_name, 'MON-YYYY')

Please help me with the group by clause

USE [MAS_CAN]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spHistorybyCalenderYear]--create a stored proc
#Year int = '2013'
AS
Begin
SET NOCOUNT ON
SELECT
isnull(round(l.UnitPrice*l.QuantityShipped,2),0) as SalesAmount,
isnull(round(l.unitCost*l.QuantityShipped,2),0) as CostAmount,
(case
when month(h.INVOICEDATE)=01 then '01'
when month(h.INVOICEDATE)=02 then '02'
when month(h.INVOICEDATE)=03 then '03'
when month(h.INVOICEDATE)=04 then '04'
when month(h.INVOICEDATE)=05 then '05'
when month(h.INVOICEDATE)=06 then '06'
when month(h.INVOICEDATE)=07 then '07'
when month(h.INVOICEDATE)=08 then '08'
when month(h.INVOICEDATE)=09 then '09'
when month(h.INVOICEDATE)=10 then '10'
when month(h.INVOICEDATE)=11 then '11'
when month(h.INVOICEDATE)=12 then '12'
END) as Period
FROM AR_INVOICEHISTORYHEADER h join AR_INVOICEHISTORYDETAIL l on (h.INVOICENO = l.INVOICENO)
Group by l.unitprice,l.unitcost,l.quantityShipped,h.invoicedate
order by Period
END
I would like to group it by period...Say I would like to see
Period SalesAmount CostAmount
01 22 19
02 24 25
Use this:
GROUP BY l.unitprice, l.unitcost, l.quantityShipped, CAST(MONTH(h.invoicedate) as varchar)
Also, you can get rid of that large case statement if you use this in its place:
SELECT
isnull(round(l.UnitPrice*l.QuantityShipped,2),0) as SalesAmount,
isnull(round(l.unitCost*l.QuantityShipped,2),0) as CostAmount,
CAST(MONTH(h.invoicedate) as varchar) as Period
FROM ...
As #Kaf mentioned, if you want Period to be 0 padded you can use either of these instead of the direct CAST:
right(100 + month(h.invoicedate),2)
left(convert(varchar, h.invoicedate, 10), 2)