Related
I have two tables:
Fee_Payable_to_Students:
f_co |S_Adm_No | apr | may | june | jul | aug | sep | oct | nov | dec | jan | feb | mar
1 |s_1 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5
2 |s_1 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5
Fee_Assign_Waiver_to_Students:
f_co|S_Adm_No | apr | may | june | jul | aug | sep | oct | nov | dec | jan | feb | mar
1 |s_1 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5
I want to view my result as
S_Adm_No | Installment | Amount |Payable_Date
s_1 |Quarter-1 (April, May & June) | 5 |Apr 15, 2018
s_1 |Quarter-2 (July, August & September) | 5 |Jul 15, 2018
s_1 |Quarter-3 (October, November & December) | 5 |Oct 15, 2018
s_1 |Quarter-4 (January, February & March) | 5 |Jan 15, 2019
My SQL query is here:
SELECT
unPvt.S_Adm_No, Installment,
SUM(Amount) AS Amount,
CASE
WHEN Installment = 'Quarter-1 (April, May & June)'
THEN 'Apr 15, 2018'
WHEN Installment = 'Quarter-2 (July, August & September)'
THEN 'Jul 15, 2018'
WHEN Installment = 'Quarter-3 (October, November & December)'
THEN 'Oct 15, 2018'
WHEN Installment = 'Quarter-4 (January, February & March)'
THEN 'Jan 15, 2019'
END AS Payable_Date
FROM
(SELECT
pc.S_Adm_No,
(Apr + May + Jun)-COALESCE(CON.Qa1,0) AS [Quarter-1 (April, May & June)],
(Jul + Aug + Sep)-COALESCE(CON.Qa2,0) AS [Quarter-2 (July, August & September)],
(Oct + Nov + Dec)-COALESCE(CON.Qa3,0) AS [Quarter-3 (October, November & December)],
(Jan + Feb + Mar)-COALESCE(CON.Qa4,0) AS [Quarter-4 (January, February & March)]
FROM
Fee_Payable_to_Students pc
LEFT JOIN
(SELECT
S_Adm_no,
SUM(E_Apr + E_May + E_Jun) Qa1,
SUM(E_Jul + E_Aug + E_Sep) Qa2,
SUM(E_Oct + E_Nov + E_Dec) Qa3,
SUM(E_Jan + E_Feb + E_Mar) Qa4
FROM
Fee_Assign_Waiver_to_Students w
GROUP BY
S_Adm_No) AS CON ON pc.S_Adm_no = CON.S_Adm_no
WHERE
pc.S_Adm_No = s_1) AS Pvt
UNPIVOT
(Amount FOR Installment IN
([Quarter-1 (April, May & June)],
[Quarter-2 (July, August & September)],
[Quarter-3 (October, November & December)],
[Quarter-4 (January, February & March)])) AS unPvt
GROUP BY unPvt.S_Adm_No,unPvt.Installment
I guess your problem is that you have a many to one relationship which when joined results in a many to many relationship so all your installments calculate out as zero. You have partly solved the problem by grouping Fee_Assign_Waiver_to_Students and you just need to apply the same thinking to Fee_Payable_to_Students. I would for clarity use a cte to do this bit. Given
drop table Fee_Payable_to_Students
go
drop table Fee_Assign_Waiver_to_Students
go
create table Fee_Payable_to_Students
(
f_co int,S_Adm_No varchar(10), apr int, may int, jun int, jul int, aug int, sep int, oct int, nov int, dec int, jan int, feb int, mar int
)
go
create table Fee_Assign_Waiver_to_Students
(
f_co int,S_Adm_No varchar(10), apr int, may int, jun int, jul int, aug int, sep int, oct int, nov int, dec int, jan int, feb int, mar int
)
go
insert into Fee_Payable_to_Students values
(1 ,'s_1' , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5),
(2 ,'s_1' , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5),
(3 ,'s_2' , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5),
(4 ,'s_3' , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5),
(5 ,'s_3' , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5)
insert into Fee_Assign_Waiver_to_Students values
(1 ,'s_1' , null , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5),
(2 ,'s_3' , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5)
This code
;with cte as(
select pc.s_adm_no,
coalesce(pa1,0) - coalesce(qa1,0) AS [Quarter-1 (April, May & June)],
coalesce(pa2,0) - coalesce(qa2,0) AS [Quarter-2 (July, August & September)],
coalesce(pa3,0) - coalesce(qa3,0) AS [Quarter-3 (October, November & December)],
coalesce(pa4,0) - coalesce(qa4,0) AS [Quarter-4 (January, February & March)]
from
(
SELECT
p.S_Adm_no,
SUM(coalesce(Apr,0) + coalesce(May,0) + coalesce(Jun,0)) pa1,
SUM(coalesce(Jul,0) + coalesce(Aug,0) + coalesce(Sep,0)) pa2,
SUM(coalesce(Oct,0) + coalesce(Nov,0) + coalesce(Dec,0)) pa3,
SUM(coalesce(Jan,0) + coalesce(Feb,0) + coalesce(Mar,0)) pa4
FROM
Fee_Payable_to_Students p
GROUP BY
S_Adm_No
) pc
left join
(SELECT
S_Adm_no,
SUM(coalesce(Apr,0) + coalesce(May,0) + coalesce(Jun,0)) Qa1,
SUM(coalesce(Jul,0) + coalesce(Aug,0) + coalesce(Sep,0)) Qa2,
SUM(coalesce(Oct,0) + coalesce(Nov,0) + coalesce(Dec,0)) Qa3,
SUM(coalesce(Jan,0) + coalesce(Feb,0) + coalesce(Mar,0)) Qa4
FROM
Fee_Assign_Waiver_to_Students w
GROUP BY
S_Adm_No) AS CON ON pc.S_Adm_no = CON.S_Adm_no
)
select unpvt.s_adm_no,unpvt.installment,unpvt.amount,
CASE
WHEN Installment = 'Quarter-1 (April, May & June)'
THEN 'Apr 15, 2018'
WHEN Installment = 'Quarter-2 (July, August & September)'
THEN 'Jul 15, 2018'
WHEN Installment = 'Quarter-3 (October, November & December)'
THEN 'Oct 15, 2018'
WHEN Installment = 'Quarter-4 (January, February & March)'
THEN 'Jan 15, 2019'
END AS Payable_Date
from
(select * from cte) as pvt
unpivot (amount for installment in ([Quarter-1 (April, May & June)],
[Quarter-2 (July, August & September)],
[Quarter-3 (October, November & December)],
[Quarter-4 (January, February & March)])) AS unPvt
Result
s_adm_no installment amount Payable_Date
---------- ---------------------------------------- ----------- ------------
s_1 Quarter-1 (April, May & June) 20 Apr 15, 2018
s_1 Quarter-2 (July, August & September) 15 Jul 15, 2018
s_1 Quarter-3 (October, November & Decem 15 Oct 15, 2018
s_1 Quarter-4 (January, February & March 15 Jan 15, 2019
s_2 Quarter-1 (April, May & June) 15 Apr 15, 2018
s_2 Quarter-2 (July, August & September) 15 Jul 15, 2018
s_2 Quarter-3 (October, November & Decem 15 Oct 15, 2018
s_2 Quarter-4 (January, February & March 15 Jan 15, 2019
s_3 Quarter-1 (April, May & June) 15 Apr 15, 2018
s_3 Quarter-2 (July, August & September) 15 Jul 15, 2018
s_3 Quarter-3 (October, November & Decem 15 Oct 15, 2018
s_3 Quarter-4 (January, February & March 15 Jan 15, 2019
Using SQL Server 2012, I am trying create a query that provides me with, say, the top 10 longest wet (or dry) periods from a climate database.
My temp table provides the following data output:
select monthid as [id], date, rain_today
from #raindays
order by monthid asc, date asc
Output:
id date rain_today
-------------------------------
1 24 Dec 2014 2.4
1 25 Dec 2014 0
1 26 Dec 2014 8.7
1 27 Dec 2014 1.8
1 28 Dec 2014 0.3
1 29 Dec 2014 0
1 30 Dec 2014 0
1 31 Dec 2014 0.3
2 01 Jan 2015 0.3
2 02 Jan 2015 0.3
2 03 Jan 2015 18.3
2 04 Jan 2015 0.3
etc. etc.
I would like to return a ranked table that would count the period where rain_today is > 0, (or rain_today = 0) i.e:
Rank Start_Date End_Date Wet Period
----------------------------------------
1 31 Dec 2014 04 Jan 2015 5
2 26 Dec 2014 28 Dec 2014 3
...
The closest I have got from reviewing other similar queries is the following (this is for dry days):
select
#raindays.monthid as id,
min(#raindays.date) as [FirstDryDay],
max(#raindays.date) as [LatestDryDay],
count(*) as countdays
from
(select
monthid,
coalesce(max(case
when rain_today > '0'
then #raindays.date end), '19000101') as latestdry
from
#raindays
group by
monthid) g
join
#raindays on #raindays.monthid = g.monthid
and #raindays.date > g.latestdry
group by
#raindays.monthid
order by
countdays desc
Output:
id FirstDryDay LatestDryDay countdays
-----------------------------------------------
23 21 Oct 2016 31 Oct 2016 11
21 23 Aug 2016 31 Aug 2016 9
**15 23 Feb 2016 29 Feb 2016 7**
10 25 Sep 2015 30 Sep 2015 6
8 28 Jul 2015 31 Jul 2015 4
24 28 Nov 2016 30 Nov 2016 3
29 29 Apr 2017 30 Apr 2017 2
30 30 May 2017 31 May 2017 2
31 29 Jun 2017 30 Jun 2017 2
20 30 Jul 2016 31 Jul 2016 2
7 29 Jun 2015 30 Jun 2015 2
5 30 Apr 2015 30 Apr 2015 1
11 31 Oct 2015 31 Oct 2015 1
17 30 Apr 2016 30 Apr 2016 1
22 30 Sep 2016 30 Sep 2016 1
As you can see, I don't really want to group by id as I want to be able to span over different months and I'm missing other periods that occur earlier in the month. The actual count is working fine correctly it seems, checking above highlighted period:
id date rain_today
15 22 Feb 2016 3.9
15 23 Feb 2016 0
15 24 Feb 2016 0
15 25 Feb 2016 0
15 26 Feb 2016 0
15 27 Feb 2016 0
15 28 Feb 2016 0
15 29 Feb 2016 0
16 01 Mar 2016 3
Thanks in advance for any help!
Is this what you want???
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
CREATE TABLE #TestData (
id INT NOT NULL ,
[Date] DATE NOT NULL,
Rain_Today DECIMAL(9,2) NOT NULL
);
INSERT #TestData (id, Date, Rain_Today) VALUES
(1, '24 Dec 2014', 2.4),
(1, '25 Dec 2014', 0),
(1, '26 Dec 2014', 8.7),
(1, '27 Dec 2014', 1.8),
(1, '28 Dec 2014', 0.3),
(1, '29 Dec 2014', 0),
(1, '30 Dec 2014', 0),
(1, '31 Dec 2014', 0.3),
(2, '01 Jan 2015', 0.3),
(2, '02 Jan 2015', 0.3),
(2, '03 Jan 2015', 18.3),
(2, '04 Jan 2015', 0.3);
--======================================
WITH
cte_AddRankGroup AS (
SELECT
td.id,
td.Date,
td.Rain_Today,
hr.HasRain,
RankGroup = DENSE_RANK() OVER (PARTITION BY td.id ORDER BY td.Date) -
DENSE_RANK() OVER (PARTITION BY td.id, hr.HasRain ORDER BY td.Date)
FROM
#TestData td
CROSS APPLY ( VALUES (IIF(td.Rain_Today = 0, 0, 1)) ) hr (HasRain)
)
SELECT
arg.id,
BegDate = MIN(arg.Date),
EndDate = MAX(arg.Date),
WetPeriod = IIF(arg.HasRain = 1, 'Wet', 'Dry'),
ConsecutiveDays = COUNT(1)
FROM
cte_AddRankGroup arg
GROUP BY
arg.id,
arg.HasRain,
arg.RankGroup
ORDER BY
arg.id,
MIN(arg.Date);
Results...
id BegDate EndDate WetPeriod ConsecutiveDays
----------- ---------- ---------- --------- ---------------
1 2014-12-24 2014-12-24 Wet 1
1 2014-12-25 2014-12-25 Dry 1
1 2014-12-26 2014-12-28 Wet 3
1 2014-12-29 2014-12-30 Dry 2
1 2014-12-31 2014-12-31 Wet 1
2 2015-01-01 2015-01-04 Wet 4
Edit: Code version using CASE expression in place of IIF...
--======================================
WITH
cte_AddRankGroup AS (
SELECT
td.id,
td.Date,
td.Rain_Today,
hr.HasRain,
RankGroup = DENSE_RANK() OVER (PARTITION BY td.id ORDER BY td.Date) -
DENSE_RANK() OVER (PARTITION BY td.id, hr.HasRain ORDER BY td.Date)
FROM
#TestData td
CROSS APPLY ( VALUES (CASE WHEN td.Rain_Today = 0 THEN 0 ELSE 1 END) ) hr (HasRain)
)
SELECT top 10
arg.id,
BegDate = MIN(arg.Date),
EndDate = MAX(arg.Date),
WetPeriod = CASE WHEN arg.HasRain = 1 THEN 'Wet' ELSE 'Dry' END,
ConsecutiveDays = COUNT(1)
FROM
cte_AddRankGroup arg
WHERE
arg.HasRain = '0' -- Top 10 Dry
--arg.HasRain = '1' -- Top 10 Wet
GROUP BY
arg.id,
arg.HasRain,
arg.RankGroup
ORDER BY
ConsecutiveDays desc, MIN(arg.Date);
Modified original script to produce the Top 10 by each period type which was my ultimate aim (output is from the full dataset):
id BegDate EndDate WetPeriod ConsecutiveDays
31 10 Jun 2017 26 Jun 2017 Dry 17
4 02 Mar 2015 14 Mar 2015 Dry 13
5 12 Apr 2015 24 Apr 2015 Dry 13
20 15 Jul 2016 26 Jul 2016 Dry 12
29 01 Apr 2017 11 Apr 2017 Dry 11
26 17 Jan 2017 27 Jan 2017 Dry 11
23 21 Oct 2016 31 Oct 2016 Dry 11
25 01 Dec 2016 09 Dec 2016 Dry 9
21 10 Aug 2016 18 Aug 2016 Dry 9
21 23 Aug 2016 31 Aug 2016 Dry 9
This problem can be resolved by recursion in this way:
-- this variable is needed to stop the recursion
declare #numrows int=(select count(1) from #raindays)
-- add a row number to the table creating a new table as "tabseq"
;WITH tabseq as (select row_number() over(order by date) as rownum, * from #raindays),
-- apply recursion to tabseq keeping a toggle running totals of wet and dry periods
CTE as
(
select *,
(case when rain_today=0 then 1 else 0 end) as dry,
(case when rain_today>0 then 1 else 0 end) as wet
from tabseq where rownum=1
union all
select s.*,
(case when s.rain_today=0 then cte.dry+1 else 0 end) as dry,
(case when s.rain_today>0 then cte.wet+1 else 0 end) as wet
from tabseq s
join cte on s.rownum=cte.rownum+1
where s.rownum<=#numrows
)
select * from cte
Once you have the table (cte) with the dry/wet accumulators you can order and select from it to suit your output requirements.
Please note that this is assuming consecutive days on the table, if there are gaps then instead of adding +1 on the case statement you may need to add a datediff to one side or the other depending how you consider the missing dates (wet or dry).
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;
SELECT ITEM, TXNDate, RIGHT(CONVERT(VARCHAR(10),PREVDATE,6),7), RIGHT(CONVERT(VARCHAR(10),DATEADD(year,1,NEXTVDATE),6),7) FROM TABLE
this retrieves as below
-------------------------------------------
ITEM | TXNDate |PREVDATE | NEXTDATE |
-------------------------------------------
item-A 03 Jan 13 Jan 13 Jan 14
item-C 06 Jan 13 Jan 13 Jan 14
item-B 08 Jan 13 Jan 13 Jan 14
item-A 05 Feb 13 Feb 13 Feb 14
item-B 07 Feb 13 Feb 13 Feb 14
item-B 16 Mar 13 Mar 13 Mar 14
item-A 03 Apr 13 Apr 13 Apr 14
_______________________________________
Here I'm trying to show dates in Ordered manner
SELECT * INTO #DATES FROM (SELECT PREVDATE DATES from #DATA
UNION
SELECT NEXTDATE DATES from #DATA) p
SELECT * FROM #DATES
But I'm getting this result
----------
| DATES |
----------
Apr 13
Apr 14
Feb 13
Feb 14
Jan 13
Jan 14
Mar 13
Mar 14
---------
Please help me to get result as
----------
| DATES |
----------
Jan 13
Jan 14
Feb 13
Feb 14
Mar 13
Mar 14
Apr 13
Apr 14
---------
You can just add ORDER BY to your last SELECT to get the dates in an ascending order:
SELECT * INTO #DATES FROM (SELECT PREVDATE DATES from #DATA
UNION
SELECT NEXTDATE DATES from #DATA) p
SELECT * FROM #DATES
ORDER BY DATEPART(MONTH, CONVERT(DATE, '01 ' + DATES)),
DATEPART(YEAR, CONVERT(DATE, '01 ' + DATES))
As your dates are strings, you need to convert them to dates. Then get the month and year parts as this is the order you want.
The ordering you want in your result is a little strange, because you want Jan 14 to be before Feb 13?
Without an ORDER BY clause you will never be certain of the way the records are ordered. Including this clause is therefore necessary, as explained here
SELECT * INTO #DATES FROM
(SELECT PREVDATE DATES from #DATA
UNION
SELECT NEXTDATE DATES from #DATA
) p
SELECT *
FROM #DATES
ORDER BY DATES
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