簡體   English   中英

SQL query_select 根據條件選擇不同的列

[英]SQL query_select different column based on condition

這是我的兩張桌子:

  • 表 1 有開始日期和結束日期。
  • Table2 有 AllMonths 和 Month 和 Value 列。

創建這些表的腳本。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM