SQL Query : How to get date reference of Month And Year Column? - sql

I need a help to change the Month & Year column as Date in Result.
Ex :
Table Name : AA
Month Year
4 2016
5 2015
Result Should Be:
01-04-2016
01-05-2015
I need a SQL query for this? Can any one help me out?

Try like this,
DECLARE #AA TABLE (
Month INT
,Year INT
)
INSERT INTO #AA (
Month
,Year
)
VALUES (
4
,2016
)
,(
5
,2015
)
SELECT convert(DATE, convert(VARCHAR(50), year * 10000 + month * 100 + 01)) AS DATE
FROM #AA

Try this code:
select '01-'+cast([month] as nvarchar) + '-'+cast([Year] as nvarchar)
from YourTable

Assuming int data types:
DECLARE #Month int = 4, #Year int = 2016
SELECT CAST(CAST(#Year * 10000 + #Month * 100 + 01 As char(8)) as date)
Assuming char/varchar data types:
DECLARE #MonthString varchar(2) = 4, #YearString char(4) = 2016
SELECT CAST(#YearString +'-'+ RIGHT('00' + #MonthString, 2) + '-01' as date)
Results in both cases:
2016-04-01 -- (Date data type)

Add square brackets for the reserve keywords:
DECLARE #AA TABLE ([Month] INT, [Year] INT);
INSERT INTO #AA ([Month], [Year]) VALUES
(4, 2016),
(5, 2015);
SELECT '01-' + RIGHT('00' + CAST([MONTH] AS VARCHAR), 2) + '-' + CAST([Year] AS VARCHAR)
FROM #AA
Result:
01-04-2016
01-05-2015

DECLARE #Table1 TABLE
(Month int, Year int)
;
INSERT INTO #Table1
(Month, Year)
VALUES
(4, 2016),
(5, 2015)
;
select '01'+'-'+RIGHT('000'+CAST(Month AS VARCHAR(3)),2)+'-'+CAST(Year AS VARCHAR) from #Table1

Do not do varchar convertions. Use like below
declare #t table([Month] int,[Year] int)
insert into #t
select 4, 2016 union all
select 5, 2015
select dateadd(month,month-1,dateadd(year,[year]-1900,0)) from #t

You can use concat function to acieve this
SELECT CONCAT('01-',year,'-',month) as req_date from tableName

try this:
declare #y varchar(4)='2015'
declare #m varchar(2)='5'
--try_prase is available starting sql 2012
print try_parse('01-'+#m+'-'+#y as datetime using 'en-us')
print convert(datetime,'01-'+#m+'-'+#y,121)

Related

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 int 20171116101856 to yyyymmddhhmmss format to be used in datediff function

So I have this table that has date columns in int type.
last_run_date | last_run_time
20171116 | 100234
Im trying to convert this two values into a datetime to be used in datediff statement.
this is my statement
SELECT 1
FROM V_Jobs_All_Servers vjas
WHERE JobName='DailyReports_xxxx' and Step_Name='xxxx'
and DATEDIFF(hour, Convert(varchar,STUFF(STUFF(STUFF(STUFF(STUFF(cast(
Convert(varchar(100),vjas.last_run_date) + Convert(varchar(100),vjas.last_run_time) as varchar)
,5,0,'-'),8,0,'-'),11,0,' '),14,0,':'),17,0,':')), Getdate()) <3
This works but only when the last_run_time value is in two digits hour format
101216, but whenever its one digit hour 91316 it fails with the following error,
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
I am on SQL Server 2005
If you're getting this value from msdb.dbo.sysjobsteps, there's a built-in function, msdb.dbo.agent_datetime(), to convert last_run_date and last_run_time to a datetime already:
select job_id,
step_id,
step_name,
msdb.dbo.agent_datetime(nullif(last_run_date,0),nullif(last_run_time,0)) as last_run_datetime
from msdb.dbo.sysjobsteps
It is an undocumented function. However, at least in my version of SQL Server (2012), that function has this definition:
CREATE FUNCTION agent_datetime(#date int, #time int)
RETURNS DATETIME
AS
BEGIN
RETURN
(
CONVERT(DATETIME,
CONVERT(NVARCHAR(4),#date / 10000) + N'-' +
CONVERT(NVARCHAR(2),(#date % 10000)/100) + N'-' +
CONVERT(NVARCHAR(2),#date % 100) + N' ' +
CONVERT(NVARCHAR(2),#time / 10000) + N':' +
CONVERT(NVARCHAR(2),(#time % 10000)/100) + N':' +
CONVERT(NVARCHAR(2),#time % 100),
120)
)
END
You are massively over complicating this, just pad your time value with a leading 0 and convert from there:
declare #t table(last_run_date int, last_run_time int);
insert into #t values(20171116,90234),(20171116,100234);
select last_run_date
,last_run_time
,convert(datetime,cast(last_run_date as nvarchar(8))
+ ' '
+ stuff(stuff(right('0' + cast(last_run_time as nvarchar(6))
,6)
,5,0,':')
,3,0,':')
,112) as DateTimeData
from #t
Output:
+---------------+---------------+-------------------------+
| last_run_date | last_run_time | DateTimeData |
+---------------+---------------+-------------------------+
| 20171116 | 100234 | 2017-11-16 09:02:34.000 |
| 20171116 | 100234 | 2017-11-16 10:02:34.000 |
+---------------+---------------+-------------------------+
Here's an ugly way...
declare #table table (last_run_date int, last_run_time int)
insert into #table
values
(20171116,100234),
(20171116,91316)
select
cast(cast(cast(last_run_date as varchar) as datetime) + ' ' + stuff(stuff(last_run_time,len(last_run_time) - 1,0,':'),len(stuff(last_run_time,len(last_run_time) - 1,0,':')) - 4,0,':') as datetime)
from #table
DECLARE #temp TABLE (last_run_date int, last_run_time int)
INSERT INTO #temp VALUES (20171116, 100234)
SELECT convert(datetime,CAST(last_run_date as varchar))
+ Convert(time, Dateadd(SECOND, Right(last_run_time,2)/1
,Dateadd(MINUTE, Right(last_run_time,4)/100
,Dateadd(hour, Right(last_run_time,6)/10000
,'1900-01-01'
)
)
)
) [DateConverted]
FROM #temp
Produces Output:
DateConverted
2017-11-16 10:02:34.000
You can see how this works by doing each part individually.
SELECT Dateadd(hour, Right(last_run_time,6)/10000
,'1900-01-01')
FROM #temp
Gives the hours position.
SELECT Dateadd(MINUTE, Right(last_run_time,4)/100
,Dateadd(hour, Right(last_run_time,6)/10000
,'1900-01-01'))
FROM #temp
Gives the hours plus minutes position.
Etc.

Need monthly report where I need summation of Qty for each day

I have one table STOCK_REGISTER where I have columns Id, ItmId, Qty, CreatedDate. And there are daily transaction data like item inward, outward and all.
Now I am developing one Monthly Report where I want to display Day wise summation of item qty for whole month. I have written following query to do so.
SELECT CONVERT(Date,CreatedDate) AS CreatedDate,ItmId, SUM(Qty)
FROM STOCK_REGISTER
GROUP BY CONVERT(Date,CreatedDate),ItmId
This query returns correct data but if I am asking for April-2017 data and STOCK_REGISTER don't have any record on 5th April then it's not displaying 5th April at all where I need 0 value in qty for that item in 5th April.
Can you help me out to get this type of data?
Edit :
I have created query which gives all days of any particular month and have applied left join with STOCK_REGISTER, but still not solving my issue.
declare #month int, #year int
set #month = 4
set #year = 2017
SELECT CAST(CAST(#year AS VARCHAR) + '-' + CAST(#Month AS VARCHAR) + '-01' AS DATETIME) + A.Number AS STKFG_CREATED_DATE,
B.STKFG_ITM_ID,
0 AS OPENING_STOCK,
SUM(STKFG_QTY)
FROM master..spt_values A
LEFT JOIN STOCK_REGISTER_FG B
ON CONVERT(DATE,CAST(CAST(#year AS VARCHAR) + '-' + CAST(#Month AS VARCHAR) + '-01' AS DATETIME) + A.Number) = CONVERT(DATE,B.STKFG_CREATED_DATE)
AND C.ITM_ID = B.STKFG_ITM_ID
WHERE type = 'P'
AND (CAST(CAST(#year AS VARCHAR) + '-' + CAST(#Month AS VARCHAR) + '-01' AS DATETIME) + A.Number ) <
DATEADD(mm,1,CAST(CAST(#year AS VARCHAR) + '-' + CAST(#Month AS VARCHAR) + '-01' AS DATETIME) )
AND STKFG_TRAT_ID = 6
GROUP BY A.Number, B.STKFG_ITM_ID
ORDER BY B.STKFG_ITM_ID,CAST(CAST(#year AS VARCHAR) + '-' + CAST(#Month AS VARCHAR) + '-01' AS DATETIME) + A.Number
Thank you for your comments.
I have found one solution which works fine for me.
Here #TEMP_TABLE contains all dates.
SELECT A.CREATED_DATE,B.ITM_NAME,ISNULL(C.STKFG_QTY,0)
FROM #TEMP_TABLE A
CROSS APPLY ITEM_MASTER B
LEFT JOIN ( SELECT CONVERT(DATE,STKFG_CREATED_DATE) AS STKFG_CREATED_DATE, STKFG_ITM_ID, SUM(STKFG_QTY) AS STKFG_QTY
FROM STOCK_REGISTER_FG GROUP BY CONVERT(DATE,STKFG_CREATED_DATE),STKFG_ITM_ID) C
ON CONVERT(DATE,A.CREATED_DATE) = CONVERT(DATE,C.STKFG_CREATED_DATE)
AND B.ITM_ID = C.STKFG_ITM_ID
ORDER BY B.ITM_NAME,A.CREATED_DATE
Try below script. Here #tblData is your actual table name.
declare #tblData table
(id int,datecolumn date)
INSERT INTO #tblData
(id,datecolumn)
SELECT 1,'2010-01-01' UNION ALL
SELECT 3,'2010-01-01' UNION ALL
SELECT 1,'2010-01-03' UNION ALL
SELECT 2,'2010-01-04' UNION ALL
SELECT 1,'2010-01-05' UNION ALL
SELECT 3,'2010-01-06' UNION ALL
SELECT 1,'2010-01-10' UNION ALL
SELECT 1,'2010-01-10' UNION ALL
SELECT 2,'2010-01-11' UNION ALL
SELECT 1,'2010-01-11' UNION ALL
SELECT 2,'2010-01-11' UNION ALL
SELECT 1,'2010-01-12' UNION ALL
SELECT 3,'2010-01-13'
DECLARE #MaxDate DATE,
#MinDate DATE,
#iDate DATE
DECLARE #DateSequence TABLE(
DATE1 DATE
)
SELECT #MaxDate = Convert(DATE,Max(datecolumn)),
#MinDate = Convert(DATE,Min(datecolumn))
FROM #tblData -- Put your month condition
SET #iDate = #MinDate
WHILE (#iDate <= #MaxDate)
BEGIN
INSERT #DateSequence
SELECT #iDate
SET #iDate = Convert(DATE,Dateadd(DAY,1,#iDate))
END
SELECT a.DATE1 ,isnull(sum(b.id),0) as total
FROM #DateSequence a left join #tblData b on a.DATE1=b.datecolumn
group by a.DATE1
Thanks,

How to sum set of period times in specific format

If I have result set like that :
Work_hour(hh:mm)
10:24
12:59
06:28
where Work_hour is of type varchar
How to sum those hours and minutes with the same format ?
SELECT CAST(FLOOR(TMP1.MINS/60) AS VARCHAR) + ':' + CAST((TMP1.MINS % 60) AS VARCHAR) FROM (
SELECT SUM (CAST(LEFT(time_column, 2) AS INT) * 60 + CAST(RIGHT(time_column, 2) AS INT)) as MINS FROM table1
) AS TMP1
Where time_column is the column in the table and table1 is the name of the table. Example:
create table table1 (
time_column varchar(10)
);
insert into table1 (time_column) values ('12:20'), ('10:40'), ('15:50');
Results in: 38:50
Try this one -
Query:
DECLARE #temp TABLE
(
work_hour CHAR(5)
)
INSERT INTO #temp (work_hour)
VALUES
('10:24'),
('12:59'),
('06:28')
;WITH cte AS
(
SELECT mn = SUM(DATEDIFF(MINUTE, '19000101', CAST('19000101 ' + work_hour AS DATETIME)))
FROM #temp
)
SELECT CAST(FLOOR(mn / 60) AS VARCHAR(5)) + ':' + CAST(mn % 60 AS VARCHAR(2))
FROM cte
Output:
hm
--------
29:51
Update 2:
DECLARE #temp TABLE
(
transtime_out DATETIME
, transtime_in DATETIME
)
INSERT INTO #temp (transtime_out, transtime_in)
VALUES
('2013-05-19 16:40:53.000', '2013-05-19 08:58:07.000'),
('2013-05-19 16:40:53.000', '2013-05-19 08:58:07.000')
SELECT diff = LEFT(CONVERT(VARCHAR(10), CAST(SUM(CAST(a.transtime_out - a.transtime_in AS FLOAT)) AS DATETIME), 108), 5)
FROM #temp a

sql : calculate the total birthday moth based on month

I want to code a query to calculate the total birthday moth based on month . Here is the sample data . Two person's bithday are April, 1980 .
How to write this query ?
John 02/21/1980
Peter 02/22/1980
Lucy 04/21/1980
------ result -----
01/1980 0
02/1980 2
03/1980 0
04/1980 1
05/1980 0
.....
You can loop for every months like this:
DECLARE #month INT
DECLARE #year INT
DECLARE #result TABLE (MonthYear varchar(7),BirthdaysCount INT)
SET #month = 1
SET #year = 1980
WHILE(#month < 13)
BEGIN
INSERT INTO #result
SELECT (CAST(#month as VARCHAR) + '/' + CAST(#year as VARCHAR)),
COUNT(*)
FROM test
WHERE MONTH(birth) = #month AND YEAR(birth) = #year
SET #month = #month + 1
END
select * from #result
See the fiddle: http://sqlfiddle.com/#!3/20692/2
In MySQL you would do this:
select concat(month(dob), '/', year(dob)) monthYear, count(*) cnt from t
group by monthYear
order by year(dob), month(dob)
However, in order to get the "missing dates" you'll have to generate data, because 01/1980 is not in any table, as far as I can see. Check this answer to see how.
how about this for sql-server
create table #temp
(
name varchar(50),
DOB datetime
)
insert into #temp values ('john', '2/21/1980')
insert into #temp values ('peter', '2/22/1980')
insert into #temp values ('lucy', '4/21/1980')
select convert(varchar(2), MONTH(DOB)) + '/' + Convert(varchar(4), YEAR(DOB)) as [MM/YYYY]
, count(*) as TotalCount
from #temp
group by convert(varchar(2), MONTH(DOB)) + '/' + Convert(varchar(4), YEAR(DOB))
drop table #temp
EDIT - This will get you all records for the dates included in the dates in the table. It will use the Min/Max Date in the table to get the date range, you then use this range to get the count of the birthdays in each month:
create table #temp
(
name varchar(50),
DOB datetime
)
insert into #temp values ('john', '2/21/1980')
insert into #temp values ('peter', '2/22/1980')
insert into #temp values ('lucy', '4/21/1980')
;with cte as
(
select min(DOB) as MinDate, max(DOB) as MaxDate
from #temp
union all
SELECT dateadd(mm, 1, t.MinDate), t.MaxDate
from cte t
where dateadd(mm, 1, t.MinDate) <= t.MaxDate
)
select convert(varchar(2), MONTH(c.MinDate)) + '/' + Convert(varchar(4), YEAR(c.MinDate))
, IsNull(t.TotalCount, 0) as TotalCount
from cte c
LEFT JOIN
(
SELECT convert(varchar(2), MONTH(DOB)) + '/' + Convert(varchar(4), YEAR(DOB)) as [MM/YYYY]
, count(*) as TotalCount
FROM #temp
group by convert(varchar(2), MONTH(DOB)) + '/' + Convert(varchar(4), YEAR(DOB))
) t
on convert(varchar(2), MONTH(C.MinDate)) + '/' + Convert(varchar(4), YEAR(C.MinDate))
= t.[MM/YYYY]
drop table #temp