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)
Related
Year
Month
Quarter
2012
1
1
2012
2
1
2012
3
1
2012
4
2
2012
5
2
2012
6
2
2012
7
3
2012
8
3
2012
9
3
2012
10
4
2012
11
4
2012
12
4
2013
1
5
2013
2
5
2013
3
5
2013
4
6
2013
5
6
2013
6
6
2013
7
7
2013
8
7
2013
9
7
2013
10
8
2013
11
8
2013
12
8
Explanation:
Year column increments by 1 after every 12 rows.
Month column goes till 12 and then resets.
Quarter column increments by 1 after every 3 rows but does not reset after year
Try a tally table to get row numbers and use modulo (%) and integer division to derive the numbers
with cteTally as (
SELECT TOP 100 ROW_NUMBER () OVER (ORDER BY NAME) -1 as MonthNumber
FROM sys.objects
)
SELECT
CEILING(MonthNumber / 12) + 2012 as CalYear
, (MonthNumber % 12) + 1 as CalMonth
, 1 + (MonthNumber / 3) as CalQuarter
FROM cteTally as T
CalYear
CalMonth
CalQuarter
2012
1
1
2012
2
1
2012
3
1
2012
4
2
2012
5
2
2012
6
2
2012
7
3
2012
8
3
2012
9
3
2012
10
4
2012
11
4
2012
12
4
2013
1
5
2013
2
5
2013
3
5
2013
4
6
2013
5
6
2013
6
6
2013
7
7
2013
8
7
2013
9
7
2013
10
8
2013
11
8
2013
12
8
I am answering posts similar to
How do you generate a fiscal calendar from a calendar year and dynamic fiscal start month with week numbers of the month in T-SQL?
I wanted to show my sql table valued function to generate fiscal calendar details from a calendar year and a specified fiscal month start.
Usage:
SELECT *
FROM [dbo].[GenerateFiscalCalendarFromCalendarYear](YEAR(GETDATE()), 8)
WHERE [CMonth] IN ( 7, 8, 9 )
AND [WeekNumOfMonth]IN(1,2);
CMonth
FMonth
FYear
CFirstDay
CLastDay
Day
WeekNumOfMonth
FYearStartMonth
7
12
2022
2022-07-01
2022-07-31
2022-07-01
1
8
7
12
2022
2022-07-01
2022-07-31
2022-07-02
1
8
7
12
2022
2022-07-01
2022-07-31
2022-07-03
2
8
7
12
2022
2022-07-01
2022-07-31
2022-07-04
2
8
7
12
2022
2022-07-01
2022-07-31
2022-07-05
2
8
7
12
2022
2022-07-01
2022-07-31
2022-07-06
2
8
7
12
2022
2022-07-01
2022-07-31
2022-07-07
2
8
7
12
2022
2022-07-01
2022-07-31
2022-07-08
2
8
7
12
2022
2022-07-01
2022-07-31
2022-07-09
2
8
8
1
2023
2022-08-01
2022-08-31
2022-08-01
1
8
8
1
2023
2022-08-01
2022-08-31
2022-08-02
1
8
8
1
2023
2022-08-01
2022-08-31
2022-08-03
1
8
8
1
2023
2022-08-01
2022-08-31
2022-08-04
1
8
8
1
2023
2022-08-01
2022-08-31
2022-08-05
1
8
8
1
2023
2022-08-01
2022-08-31
2022-08-06
1
8
8
1
2023
2022-08-01
2022-08-31
2022-08-07
2
8
8
1
2023
2022-08-01
2022-08-31
2022-08-08
2
8
8
1
2023
2022-08-01
2022-08-31
2022-08-09
2
8
8
1
2023
2022-08-01
2022-08-31
2022-08-10
2
8
8
1
2023
2022-08-01
2022-08-31
2022-08-11
2
8
8
1
2023
2022-08-01
2022-08-31
2022-08-12
2
8
8
1
2023
2022-08-01
2022-08-31
2022-08-13
2
8
9
2
2023
2022-09-01
2022-09-30
2022-09-01
1
8
9
2
2023
2022-09-01
2022-09-30
2022-09-02
1
8
9
2
2023
2022-09-01
2022-09-30
2022-09-03
1
8
9
2
2023
2022-09-01
2022-09-30
2022-09-04
2
8
9
2
2023
2022-09-01
2022-09-30
2022-09-05
2
8
9
2
2023
2022-09-01
2022-09-30
2022-09-06
2
8
9
2
2023
2022-09-01
2022-09-30
2022-09-07
2
8
9
2
2023
2022-09-01
2022-09-30
2022-09-08
2
8
9
2
2023
2022-09-01
2022-09-30
2022-09-09
2
8
9
2
2023
2022-09-01
2022-09-30
2022-09-10
2
8
-- ================================================
-- Template generated from Template Explorer using:
-- Create Multi-Statement Function (New Menu).SQL
--
-- Use the Specify Values for Template Parameters
-- command (Ctrl-Shift-M) to fill in the parameter
-- values below.
--
-- This block of comments will not be included in
-- the definition of the function.
-- ================================================
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
-- =============================================
-- Author: Jay Asbury
-- Create date: 8/5/2022
-- Description: Generates Calendar to Fiscal year Table for a year.
-- =============================================
CREATE FUNCTION [dbo].[GenerateFiscalCalendarFromCalendarYear] (
-- Add the parameters for the function here
#CalendarYear INT,
#FicalYearStartMonth INT)
RETURNS TABLE
--(
---- Add the column definitions for the TABLE variable here
--[CMonth] INT,
--[FMonth] INT,
--[FYear] INT,
--[CFirstDay] DATE,
--[CLastDay] DATE,
--[Day] DATE,
--[WeekNumOfMonth] INT,
--[FYearStartMonth] INT)
AS
RETURN ( WITH [months]
AS (SELECT 1 [CMonth]
UNION ALL
SELECT [CMonth] + 1
FROM [months]
WHERE [months].[CMonth] <= 11),
[Fyears]
AS (SELECT *,
CASE
WHEN [months].[CMonth] >= #FicalYearStartMonth THEN #CalendarYear + 1
ELSE #CalendarYear END [FYear],
#CalendarYear [Cyear]
FROM [months]),
[Ranges]
AS (SELECT *,
DATEFROMPARTS([Fyears].[Cyear], [Fyears].[CMonth], 1) [CFirstDay],
EOMONTH(DATEFROMPARTS([Fyears].[Cyear], [Fyears].[CMonth], 1)) [CLastDay],
MONTH(
DATEADD(
MONTH,
MONTH(DATEFROMPARTS([Fyears].[Cyear], [Fyears].[CMonth], 1)) - #FicalYearStartMonth,
DATEFROMPARTS(
DATEPART(YEAR, DATEFROMPARTS([Fyears].[Cyear], [Fyears].[CMonth], 1)), 1, 1))) [FMonth]
FROM [Fyears]),
[Days]
AS (SELECT [Ranges].[CMonth],
[Ranges].[FMonth],
[Ranges].[FYear],
[Ranges].[CFirstDay],
[Ranges].[CLastDay],
[Ranges].[CFirstDay] [Day]
FROM [Ranges]
UNION ALL
SELECT [Days].[CMonth],
[FMonth],
[Days].[FYear],
[Days].[CFirstDay],
[Days].[CLastDay],
DATEADD(DAY, 1, [Days].[Day]) [Day]
FROM [Days]
WHERE DATEADD(DAY, 1, [Days].[Day]) <= [Days].[CLastDay])
SELECT [Days].[CMonth],
[Days].[FMonth],
[Days].[FYear],
[Days].[CFirstDay],
[Days].[CLastDay],
[Days].[Day],
(DATEPART(WEEK, [Days].[Day]) - DATEPART(WEEK, DATEADD(DAY, 1, EOMONTH([Days].[Day], -1)))) + 1 [WeekNumOfMonth],
#FicalYearStartMonth [FYearStartMonth]
FROM [Days]);
GO
SELECT *
FROM [dbo].[GenerateFiscalCalendarFromCalendarYear](YEAR(GETDATE()), 8)
WHERE [CMonth] IN ( 7, 8, 9 )
AND [WeekNumOfMonth] IN ( 1, 2 );
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
)
friends:
I'm now have a problem about conditional calculation in SQL Server.
I have set some data from SQL Server as an example in excel like this:
No Employee Month Commission1 Commission2
1 A Jan 10 5
2 A Jan 10 4
3 B Jan 15 3
4 B Jan 15 4
5 C Jan 10 3
6 C Jan 10 4
7 D Jan 13 3
8 D Jan 13 4
9 DM Jan 0 6
10 DM Jan 0 8
11 A Feb 15 4
12 A Feb 15 5
13 B Feb 20 5
14 B Feb 20 4
15 C Feb 9 3
16 C Feb 9 4
17 D Feb 14 5
18 D Feb 14 6
19 DM Feb 0 13
20 DM Feb 0 10
And the result I want is like this:
Employee Jan No# Feb No#
A 20 2 30 2
B 30 2 40 2
C 20 2 18 2
D 26 2 28 2
DM 44 10 59 10
For every sales,Employee A,B,C,D only have commission1 as payment,the commission2 is for DM. So , in Jan , DM's commission is SUM(E2:E9)
I can do it easy in excel , but how can I do this in sql server?
I make my try code like this:
select [Month],Employee,SUM(Commission1) Commission,count(distinct([No])) No#
from table1
WHERE Employee IN ('A','B','C','D')
group by [Month],Employee
union
select 'DM' as Employee,[Month],SUM(Commission2) Commission,count(distinct([No])) No#
from table1
WHERE Employee IN ('A','B','C','D','DM')
group by [Month],Employee
And I get the result
Employee Month Commission No#
A Jan 20 2
B Jan 30 2
C Jan 20 2
D Jan 26 2
DM Jan 44 10
A Feb 30 2
B Feb 40 2
C Feb 18 2
D Feb 28 2
DM Feb 59 10
The result format is not what I want.I tried pivot after this query,but failed,it seems I only can pivot one state?
Another question: If I want the month growth automatic (In actual data , there's not only Jan and Feb) in the result ,not write [Jan],[Feb],[Mar]... in pivot code, how to do it?
Who can help me?
Thanks!
Here is a PIVOT solution:
Test data:
DECLARE #t table(Employee varchar(2), Month char(3), Commission1 int, Commission2 int)
INSERT #t values
('A','Jan',10,5 ),('A','Jan',10,4),('B','Jan',15,3),
('B','Jan',15,4 ),('C','Jan',10,3),('C','Jan',10,4),
('D','Jan',13,3 ),('D','Jan',13,4),('DM','Jan',0,6),
('DM','Jan',0,8 ),('A','Feb',15,4),('A','Feb',15,5),
('B','Feb',20,5 ),('B','Feb',20,4),('C','Feb',9,3),
('C','Feb',9,4 ),('D','Feb',14,5),('D','Feb',14,6),
('DM','Feb',0,13),('DM','Feb',0,10)
Query:
;WITH CTE as
(
SELECT
Employee, Month,
CASE WHEN Employee = 'DM' THEN
SUM(Commission2) over (partition by [Month])
ELSE Commission1 END com,
CASE WHEN Employee = 'DM'
THEN row_number() over
(PARTITION BY Employee, [Month] ORDER BY (SELECT 1)) ELSE 1 END rn
FROM #t
)
SELECT Employee, [Jan], [Feb], [Mar] -- add more months
FROM
CTE
PIVOT
(SUM(com)
FOR [Month] IN ([Jan], [Feb], [Mar])) AS pvt -- add more months
WHERE rn = 1
Result:
Employee Jan Feb Mar
A 20 30 NULL
B 30 40 NULL
C 20 18 NULL
D 26 28 NULL
DM 44 59 NULL
In SqlServer you can do so using PIVOT operator as like below:
Please refer PIVOT syntax
select tmp.employee,pv.[jan] as Jan_Commission, pv.[feb] as Feb_Commission from
(
select employee,month,commission1 from table_name
)tmp
pivot (
sum(commission1)
for [month] in ([jan],[feb])
)pv;
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