T-SQL: combine current year and month from month column - sql-server

I am trying to combine current year in the form of YYYY with the monthy from the month column.
monthy monthsname
------------------------
1 January
2 February
3 March
4 April
5 May
6 June
7 July
8 August
9 September
10 October
11 November
12 December
Here is the output I am getting:
monthy monthsname month_number
------------------------------------
5 May NULL
6 June NULL
8 August NULL
9 September NULL
10 October NULL
11 November NULL
1 January 201701
2 February 201702
3 March 201703
4 April 201704
7 July 201707
12 December 201712
Instead of month_number being null, I was trying to do this:
isnull(ss.month_number, cast(convert(varchar(4), DATEPART(year, getdate())) as int) + right('0-- ' + cast(convert(varchar(2), monthy) as int), 2))
I am not getting the right output: I want something like 201705 for the first row record for month_number

Depending on what your datatype is, you might want to cast this but it's simply the year * 100 plus the month number to get the integer representation of the number you are trying to create.
ISNULL(month_number,YEAR(GETDATE())*100+monthy)

Can you try this:
SELECT
CONVERT(VARCHAR(4),DATEPART(YEAR, GETDATE())) + --year
(
REPLICATE('0', 2 - LEN(CONVERT(VARCHAR(2), monthy)) ) +
CONVERT(VARCHAR(2), monthy) --monthy
)

Related

Convert Month Days Into Weekdays Per Week In SQL

I have a calendar table and I want to show each month in a grid, and when I select a month from the table, I have some row with monthday and weekday columns, but I must convert it to multiple rows per week to show the month in the grid.
my select command to get month info is something like this
SELECT Monthday, Weekday FROM Calendar Where Month = 5
that Results to this :
Monthday | Weekday
--------- --------
1 4
2 5
3 6
4 7
5 1
6 2
7 3
8 4
. .
. .
. .
and I Want to Convert it To Something like this
1 | 2 | 3 | 4 | 5 | 6 | 7
-- --- --- --- --- --- --
1 2 3 4
5 6 7 8 . . .
just like a calendar grid.
I think the answer is by Pivot, but I don't know how, Do you know a solution how to convert my select command?
Let's suppose you have a calendar table with the structure mentioned below, which is populated with a query like the following:
CREATE TABLE Calendar (
TheDate DATE PRIMARY KEY,
YearNumber SMALLINT,
MonthNumber SMALLINT,
DayNumber SMALLINT,
WeekdayNumber SMALLINT
)
INSERT INTO dbo.Calendar (TheDate, YearNumber, MonthNumber, DayNumber, WeekdayNumber)
SELECT x.TheDate,
YEAR(x.TheDate) AS YearNumber, MONTH(x.TheDate) AS MonthNumber, DAY(x.TheDate) AS DayNumber,
(DATEPART(WEEKDAY,x.TheDate)+##DATEFIRST-2)%7+1 AS WeekdayNumber
FROM (
SELECT TOP 365 DATEADD(DAY,N-1,'20210101') AS TheDate
FROM (SELECT ROW_NUMBER() OVER (ORDER BY low) AS N FROM master..spt_values) t
ORDER BY N
) x
The formula for WeekdayNumber is written this way to ignore the SET DATEFIRST setting and always consider Monday as the first day of week. If you prefer another day to be the first in the week, adjust -2 to another value.
To display something like a calendar for a particular month, you can use a query like this:
SELECT * FROM (
SELECT DayNumber, WeekdayNumber,
DENSE_RANK() OVER (ORDER BY DayNumber-WeekdayNumber) AS WeekNumber
FROM dbo.Calendar WHERE YearNumber=2021 AND MonthNumber=5
) t
PIVOT (MAX(DayNumber) FOR WeekdayNumber IN ([1],[2],[3],[4],[5],[6],[7])) p
This produces the following result:
WeekNumber 1 2 3 4 5 6 7
-------------------- ------ ------ ------ ------ ------ ------ ------
1 NULL NULL NULL NULL NULL 1 2
2 3 4 5 6 7 8 9
3 10 11 12 13 14 15 16
4 17 18 19 20 21 22 23
5 24 25 26 27 28 29 30
6 31 NULL NULL NULL NULL NULL NULL
I am using just the DayNumber and WeekdayNumber columns to compute a week number and then I am using PIVOT to arrange the values for DayNumber in the desired format.

T-SQL Select dates Sunday through Saturday (2 weeks apart) from Dates table for the last n months

I'm trying to select specific date ranges from a dates table and assign a week number (2 weeks = 1 week). Say I have the following table:
Date WeekOfYear WeekDayName
12/26/2019 52 Thursday
12/27/2019 52 Friday
12/28/2019 52 Saturday
12/29/2019 53 Sunday
12/30/2019 53 Monday
12/31/2019 53 Tuesday
1/1/2020 1 Wednesday
1/2/2020 1 Thursday
1/3/2020 1 Friday
1/4/2020 1 Saturday
1/5/2020 2 Sunday
1/6/2020 2 Monday
1/7/2020 2 Tuesday
1/8/2020 2 Wednesday
1/9/2020 2 Thursday
1/10/2020 2 Friday
1/11/2020 2 Saturday
1/12/2020 3 Sunday
1/13/2020 3 Monday
1/14/2020 3 Tuesday
1/15/2020 3 Wednesday
1/16/2020 3 Thursday
1/17/2020 3 Friday
1/18/2020 3 Saturday
1/19/2020 4 Sunday
1/20/2020 4 Monday
1/21/2020 4 Tuesday
1/22/2020 4 Wednesday
1/23/2020 4 Thursday
1/24/2020 4 Friday
1/25/2020 4 Saturday
1/26/2020 5 Sunday
1/27/2020 5 Monday
1/28/2020 5 Tuesday
1/29/2020 5 Wednesday
1/30/2020 5 Thursday
1/31/2020 5 Friday
2/1/2020 5 Saturday
2/2/2020 6 Sunday
2/3/2020 6 Monday
2/4/2020 6 Tuesday
2/5/2020 6 Wednesday
2/6/2020 6 Thursday
2/7/2020 6 Friday
2/8/2020 6 Saturday
2/9/2020 7 Sunday
2/10/2020 7 Monday
2/11/2020 7 Tuesday
2/12/2020 7 Wednesday
2/13/2020 7 Thursday
2/14/2020 7 Friday
2/15/2020 7 Saturday
2/16/2020 8 Sunday
2/17/2020 8 Monday
2/18/2020 8 Tuesday
2/19/2020 8 Wednesday
2/20/2020 8 Thursday
2/21/2020 8 Friday
2/22/2020 8 Saturday
2/23/2020 9 Sunday
2/24/2020 9 Monday
2/25/2020 9 Tuesday
2/26/2020 9 Wednesday
2/27/2020 9 Thursday
2/28/2020 9 Friday
2/29/2020 9 Saturday
3/1/2020 10 Sunday
3/2/2020 10 Monday
3/3/2020 10 Tuesday
3/4/2020 10 Wednesday
3/5/2020 10 Thursday
3/6/2020 10 Friday
3/7/2020 10 Saturday
3/8/2020 11 Sunday
3/9/2020 11 Monday
3/10/2020 11 Tuesday
3/11/2020 11 Wednesday
3/12/2020 11 Thursday
3/13/2020 11 Friday
3/14/2020 11 Saturday
3/15/2020 12 Sunday
3/16/2020 12 Monday
3/17/2020 12 Tuesday
3/18/2020 12 Wednesday
3/19/2020 12 Thursday
3/20/2020 12 Friday
3/21/2020 12 Saturday
3/22/2020 13 Sunday
3/23/2020 13 Monday
3/24/2020 13 Tuesday
3/25/2020 13 Wednesday
My end goal would like this:
WeekNum SundayDate SaturdayDate
1 12/29/2019 1/11/2020
2 1/12/2020 1/25/2020
3 1/26/2020 2/8/2020
4 2/9/2020 2/22/2020
5 2/23/2020 3/7/2020
6 3/8/2020 3/21/2020
If I were to do this across several years, the max WeekNum would be either 26 or 27 depending on the year.
I've attempted several different queries but can't quite get the calculation right:
with MinDate_cte (Cut, MinDate)
as (select Cut = (((WeekOfYear + 1) % 52) / 2) + 1, MinDate = Date
from DimDate
where (datediff(day, Date, dateadd(day, 7 - datepart(weekday, getdate()), getdate())) % 14) = 0
and Date between dateadd(month, -7, dateadd(day, 7 - datepart(weekday, getdate()), getdate())) -- Sunday 7 months ago
and dateadd(day, 7 - datepart(weekday, getdate()), getdate()) -- next upcomming Saturday
)
select Cut = (((WeekOfYear + 1) % 52) / 2) + 1, MaxDate = dateadd(day, 1, Date), MinDate
from DimDate
join MinDate_cte on MinDate_cte.Cut = (((WeekOfYear + 1) % 52) / 2) + 1
where (datediff(day, Date, dateadd(day, 7 - datepart(weekday, getdate()), getdate())) % 14) = 0
and Date between dateadd(month, -7, dateadd(day, 7 - datepart(weekday, getdate()), getdate())) -- Sunday 7 months ago
and dateadd(day, 7 - datepart(weekday, getdate()), getdate()) -- next upcomming Saturday
and dateadd(day, 1, Date) > MinDate
order by Date
I would use much easier SQL and just work off the Sundays. This is untested as I just typed this in here but it should be right or close.
--this is your date range
declare #startdate date = '20191229'
,#enddate date = '20200331'
select WeekNum = row_number() over (order by [Sunday]),*
from (
select date as [Sunday]
, dateadd(day,14,date) as [Saturday]
, rn = row_number() over (order by date)
from [your table]
where WeekDayName = 'Sunday'
and date between #startdate and #enddate) a
where rn % 2 = 1

Month start from user define

enter image description here
The requirements says that each month starts from the 22nd and end on next month 21st.
our company Month start from 22nd each month and last day of month is 21st so i need to calculation regard compnay months
for example
date output
22nd Oct 2017 to 21st Nov 2017 = Nov 2017
22nd Nov 2017 to 21st Dec 2017 = Dec 2017
22nd Dec 2017 to 21st Jan 2018 = Jan 2018
22nd Jan 2018 to 21st Feb 2018 = Feb 2018
so when i run the query so it will look on dates and give me month name with year
Changed my answer as per your comments.
Try the code yourself here: http://sqlfiddle.com/#!6/4b3e5/5
declare #MyTable table (MyDate datetime)
insert into #MyTable (MyDate)
values ('20171022'), ('20171121'), ('20171122'), ('20171221'), ('20171222'), ('20180121'), ('20180221')
select t.MyDate,
case when datepart(day, t.MyDate) > 21 then datename(month, dateadd(month, 1, t.MyDate)) + ' ' + datename(year, dateadd(month, 1, t.MyDate))
else datename(month, t.MyDate) + ' ' + datename(year, t.MyDate)
end
from #MyTable t
the result now is
MyDate | COLUMN1
------------|--------------
22/10/2017 | November 2017
21/11/2017 | November 2017
22/11/2017 | December 2017
21/12/2017 | December 2017
22/12/2017 | January 2018
21/01/2018 | January 2018
21/02/2018 | February 2018
If you only need the first 3 chars from month, use the substring to get them like this
select t.MyDate,
case when datepart(day, t.MyDate) > 21 then substring(datename(month, dateadd(month, 1, t.MyDate)), 1, 3) + ' ' + datename(year, dateadd(month, 1, t.MyDate))
else substring(datename(month, t.MyDate), 1, 3) + ' ' + datename(year, t.MyDate)
end
from #MyTable t
Now the result is
MyDate | COLUMN1
------------|--------------
22/10/2017 | Nov 2017
21/11/2017 | Nov 2017
22/11/2017 | Dec 2017
21/12/2017 | Dec 2017
22/12/2017 | Jan 2018
21/01/2018 | Jan 2018
21/02/2018 | Feb 2018

How to query a SQL Server table with Months Range

I have a SQL Server table that have data store in this format, I want to extract data from March 2014 to Feburary 2015, how can I achieve this, please?
ID Months Years fd1 fd2 fd3 fd4
-------------------------------------------
1 january 2014 1 2 3 8
2 february 2014 2 2 2 5
3 march 2014 2 5 3 5
4 april 2014 3 4 2 2
5 may 2014 4 1 3 2
6 june 2014 1 1 2 2
7 july 2014 2 3 3 4
8 august 2014 5 6 2 5
9 september 2014 12 2 5 6
10 october 2014 11 1 5 3
11 november 2014 1 5 5 7
12 december 2014 3 8 5 8
13 january 2015 4 1 8 1
14 february 2015 5 9 8 4
15 march 2015 6 2 2 5
16 april 2015 6 5 20 2
17 may 2015 6 2 2 2
18 june 2015 9 5 2 2
19 july 2015 10 6 2 2
20 august 2015 12 3 2 5
21 september 2015 55 2 2 2
22 october 2015 1 1 2 5
23 november 2015 3 5 5 2
24 december 2015 2 5 5 5
First you should convert Years and Months columns to a DATE field(Here named as Dates).
Then compare the wanted date on Dates column.
WITH cte(ID, Months, Years, fd1, fd2, fd3, fd4, Dates)
AS
(
SELECT ID, Months, Years, fd1, fd2, fd3, fd4, CAST(CAST(Years AS NVARCHAR) + ' ' + CAST(Months AS NVARCHAR) AS DATE)
FROM tblYearMonth
)
SELECT *
FROM cte
WHERE Dates >= '2014 March' AND Dates <= '2015 February'
ORDER BY Dates
SELECT *
FROM YourTableName
WHERE (MONTH(Months+ ' 1 2014') IN (1,2) AND Years = 2015) OR (MONTH(Months+ ' 1 2014') > 2 AND Years = 2014)

sql server - help in query

I have a table called employee_salary_master in which we keep salary effective dates and entry dates of each employee in the company.
For processing salary of an employee for a month, we need to fetch most recently entered record. If the effective date is less than
that month then we pick the most recent entry. but if effective date is greater than the first date of the month, then there will be more than
one effective dates for that month
example: the data for an employee is as below.
SAL_MATSER_ID EMPLOYEE_ID EFFECTIVE_DATE ENTRY_DATE
------------- ----------- -------------- ------------
1 5814 Jan 6 2006 Jan 12 2006
2 5814 Jan 10 2006 Jul 17 2006
3 5814 Jan 20 2006 Dec 22 2006
4 5814 May 10 2007 Jul 18 2007
5 5814 Nov 1 2007 Dec 18 2007
6 5814 Aug 1 2008 Aug 20 2008
7 5814 May 1 2008 Sep 2 2008
8 5814 Sep 1 2009 Sep 18 2008
9 5814 Nov 1 2008 Apr 20 2009
10 5814 Nov 10 2009 Nov 25 2009
11 5814 Nov 5 2009 Nov 26 2009
If i need to get the record for Nov 2009, I write the query below
select EMPLOYEE_SALARY_MASTER_ID, EMPLOYEE_ID, EFFECTIVE_DATE, ENTRY_DATE, ARREAR_PROCESS_FLAG from employee_salary_master esm where employee_id = 5814
and (esm.entry_date = (select max(entry_date) from employee_salary_master where employee_id = 5814 and effective_date <= #monthfirstdate)
or (esm.effective_date between #monthfirstdate and #monthlastdate))
which gives the result below..
SAL_MATSER_ID EMPLOYEE_ID EFFECTIVE_DATE ENTRY_DATE
------------- ----------- -------------- ------------
9 5814 Nov 1 2008 Apr 20 2009
10 5814 Nov 10 2009 Nov 25 2009
11 5814 Nov 5 2009 Nov 26 2009
What I need is as follows...
For Nov 1 - Nov 4, salary should be processed as per employee_salary_masterId - 9 and
Nov 5 - Nov 30, salary should be processed as per employee_salary_masterId - 11.
SAL_MATSER_ID EMPLOYEE_ID EFFECTIVE_DATE ENTRY_DATE
------------- ----------- -------------- ------------
9 5814 Nov 1 2008 Apr 20 2009
11 5814 Nov 5 2009 Nov 26 2009
Please help me build this query.
Not quite sure if I understand you completely correct, but have a look at this example
DECLARE #employee_salary_master TABLE(
EMPLOYEE_SALARY_MASTER_ID INT,
EMPLOYEE_ID INT,
EFFECTIVE_DATE DATETIME,
ENTRY_DATE DATETIME
)
INSERT INTO #employee_salary_master SELECT 1,5814,'Jan 6 2006','Jan 12 2006'
INSERT INTO #employee_salary_master SELECT 2,5814,'Jan 10 2006','Jul 17 2006'
INSERT INTO #employee_salary_master SELECT 3,5814,'Jan 20 2006','Dec 22 2006'
INSERT INTO #employee_salary_master SELECT 4,5814,'May 10 2007','Jul 18 2007'
INSERT INTO #employee_salary_master SELECT 5,5814,'Nov 1 2007','Dec 18 2007'
INSERT INTO #employee_salary_master SELECT 6,5814,'Aug 1 2008','Aug 20 2008'
INSERT INTO #employee_salary_master SELECT 7,5814,'May 1 2008','Sep 2 2008'
INSERT INTO #employee_salary_master SELECT 8,5814,'Sep 1 2009','Sep 18 2008'
INSERT INTO #employee_salary_master SELECT 9,5814,'Nov 1 2008','Apr 20 2009'
INSERT INTO #employee_salary_master SELECT 10,5814,'Nov 10 2009','Nov 25 2009'
INSERT INTO #employee_salary_master SELECT 11,5814,'Nov 5 2009','Nov 26 2009'
DECLARE #monthfirstdate DATETIME,
#monthlastdate DATETIME
SELECT #monthfirstdate = '01 Nov 2009',
#monthlastdate = '30 Nov 2009'
SELECt *
FROM (
SELECT TOP 1
*
FROM #employee_salary_master esm
WHERE esm.EFFECTIVE_DATE BETWEEN #monthfirstdate and #monthlastdate
AND esm.EFFECTIVE_DATE < esm.ENTRY_DATE
ORDER BY esm.ENTRY_DATE DESC
) sub
UNION ALL
SELECT *
FROM (
SELECT TOP 1
*
FROM #employee_salary_master esm
WHERE esm.EFFECTIVE_DATE <= #monthfirstdate
AND esm.EFFECTIVE_DATE < esm.ENTRY_DATE
ORDER BY esm.EFFECTIVE_DATE DESC
) sub
ORDER BY EFFECTIVE_DATE
The rule for excluding nov 10 record is that we need to filter out those records for the month of November in which entry_date is greater but effective_date is smaller.
Let me explain you wrt data provided:
As a rule, the latest/last entry will take precedence over the previous entries in a particular month which implies that the entrty date of Nov 26 2009 would take precedence over the entry date of Nov 25 2009. Now since effective date of SAL_MATSER_ID - 10 is greater than that of SAL_MATSER_ID - 11, hence Nov 10 record would be nullified.
Had the data been like the below, all the 3 records would have been used for salary processing.
SAL_MATSER_ID - 9 for salary of Nov 1 - Nov 9
SAL_MATSER_ID - 10 for salary of Nov 10 - Nov 14
SAL_MATSER_ID - 11 for salary of Nov 15 - Nov 30
SAL_MATSER_ID EMPLOYEE_ID EFFECTIVE_DATE ENTRY_DATE
------------- ----------- -------------- ------------
9 5814 Nov 1 2008 Apr 20 2009
10 5814 Nov 10 2009 Nov 25 2009
11 5814 Nov 15 2009 Nov 26 2009
But since SAL_MATSER_ID - 11 is applicable from 5th Nov. onwards, the previous record is nullified. I hope this explains the situation.
Thanks for your support,
Sweta

Resources