[英]SQL query_select different column based on condition
這是我的兩張桌子:
創建這些表的腳本。
CREATE TABLE [dbo].[Table1](
[EmployeeId] [int] NULL,
[CompanyId] [int] NULL,
[StartDate] [datetime] NULL,
[EndDate] [datetime] NULL
) ON [PRIMARY]
INSERT INTO [dbo].[Table1] VALUES(12345,1205,'2021-01-01 00:00:00.000','2021-06-30 00:00:00.000')
INSERT INTO [dbo].[Table1] VALUES(23211,1205,'2021-01-01 00:00:00.000','2021-05-31 00:00:00.000')
INSERT INTO [dbo].[Table1] VALUES(23211,1205,'2021-07-01 00:00:00.000','2021-09-30 00:00:00.000')
INSERT INTO [dbo].[Table1] VALUES(23141,1205,'2021-01-01 00:00:00.000','2021-11-30 00:00:00.000')
CREATE TABLE [dbo].[Table2](
[EmployeeId] [int] NULL,
[CompanyId] [int] NULL,
[AllMonths] [int] NULL,
[Month] [int] NULL,
[Value] [int] NULL
)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,1,1)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,2,1)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,3,1)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,4,2)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,5,2)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,6,2)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,7,2)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,8,2)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,9,2)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,11,2)
INSERT INTO [dbo].[Table2] VALUES(23211,1205,NULL,12,2)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(23141,1205,1,NULL,NULL)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,1,1)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,2,1)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,3,1)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,4,1)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,5,1)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,6,1)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,7,1)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,8,2)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,9,2)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,11,2)
INSERT INTO [dbo].[Table2] VALUES(12345,1205,NULL,12,2)
我想要的 output 是:
案例 #1:員工 ID = 12345
AllMonths
列是 NULL。 Startdate
Jan 和EndDate
Nov。從 jan-nov 開始的所有這些月份在表 2 中具有相同的值。因此“Final”值為 1。
案例 #2:員工 ID = 23221
AllMonths
列是 NULL。 Startdate
一月和EndDate
日期五月。 Jan-Mar 的值為 1,而 Apr-May 在表 2 中的值為 2。因此在 output 中,應將其分成兩行,Jan-Mar 的“Final”值為 1,Apr-May 的值為 2 .
案例 #3:EmployeeId = 23141
AllMonths
列不是 NULL。 因此, AllMonths
列中的“最終”值為 1。
需要一些幫助來實現這一目標。
有2個邏輯,
i) 當 allmonths 是 null ii) allmonths 不是 null
首先以您想要的任何方式創建數字表,
Create Table tblNumber(Number int primary key)
INSERT INTO tblNumber
SELECT TOP 100000 ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS [N]
FROM dbo.syscolumns tb1,dbo.syscolumns tb2
最終腳本,
select *
,ROW_NUMBER()over( partition by employeeid order by companyid)rn1
into #table1
from table1
;with CTE as
(
select T1.*
,ROW_NUMBER()over(partition by rn1,employeeid order by companyid)rn
,ROW_NUMBER()over(partition by employeeid order by companyid)rn2
,DATEDIFF(month,startdate,enddate)+1monthDiff from #table1 T1
inner join [dbo].[tblNumber1] n on n.number<=(DATEDIFF(month,startdate,enddate)+1)
)
,CTE2 as
(
select T1.*
,dateadd(month,(rn-1),t1.startdate)NewEndDate
from CTE T1
)
,CTE1 as
(
select t1.companyid,t1.employeeid,t1.startdate,dateadd(month,(rn-1),t1.startdate)NewEndDate
,t1.Enddate,rn,rn1
,t2.[value] as Final
from CTE2 t1
cross apply(select top 1 [value] from table2 t2 where t2.employeeid=t1.employeeid
and t2.companyid=t1.companyid and month=month(NewEndDate) and allmonths is null)t2
union all
select t1.companyid,t1.employeeid,t1.startdate,dateadd(month,(rn-1),t1.startdate)NewEndDate
,t1.Enddate,rn,rn1
,t2.[allmonths] as Final
from CTE2 t1
cross apply(select top 1 allmonths from table2 t2 where t2.employeeid=t1.employeeid
and t2.companyid=t1.companyid and allmonths is not null)t2
)
select companyid, employeeid,min(NewEndDate)StartDate,max(NewEndDate) EndDate,Final
from CTE1
group by companyid, employeeid,Final,rn1
order by employeeid,Final
drop table #table1
注意事項
i)我幾個小時前采集了樣本數據。
ii) 使用其他樣本數據進行測試,如果它不適用於其他樣本數據,則單獨粘貼該樣本數據。
iii)兩個表都涉及多少行?
iv) 首先讓 output 得到糾正,然后可以優化查詢。
v) 使用各種樣本數據進行“allmonths 為空”時的第一次測試
vi) 然后用各種樣本數據測試“allmonths is not null”
這將從您提供的示例數據中返回您想要的 output:
SELECT
t1.CompanyId
,t1.EmployeeId
,StartDate = FORMAT(ISNULL(DATEFROMPARTS(YEAR(StartDate), min(t2.month), 1), StartDate), 'MM/dd/yyyy')
,EndDate = FORMAT(
ISNULL(
DATEFROMPARTS(YEAR(enddate), max(t2.month), 1)
,DATEADD(dd, -DATEPART(dd, enddate) + 1, enddate)
)
, 'MM/dd/yyyy')
,ISNULL(Allmonths, value) as Final
FROM [Table1] t1
INNER JOIN [Table2] t2 on t1.employeeid = t2.employeeid
AND t1.CompanyId = t2.CompanyId
AND ( (t2.allmonths IS NOT NULL)
OR (t2.month BETWEEN DATEPART(MM, startdate) AND DATEPART(MM, enddate))
)
GROUP BY
t1.CompanyId
,t1.EmployeeId
,StartDate
,EndDate
,ISNULL(Allmonths, value)
ORDER BY
1, 3, 4
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.