如何根据日期范围加入这些表

时间:2017-02-10 11:27:36

标签: mysql sql-server

我有2个表:Saleorder和Material在底部,

表Saleorder:

Saleorder    Datecreated    Material
A                2016-01-01      M1
B                2016-01-21      M1
C               2016-03-01       M1

和材料:

Material    Changedon    Materialresponsible
M1            2016-01-01        E
M1            2016-01-20        F
M1            2016-02-26       G

现在我想加入表Saleorder与表材料基于材料和Datecreated和changeondate,我希望得到这样的结果:

Saleorder    Datecreated    Material    materialresponsible
A                2016-01-01      M1              E
B                2016-01-21      M1              F
C               2016-03-01       M1              G

Datecreated和Changedon日期之间关系的逻辑是:

-Order A创建于2016年1月1日,当天,有物质负责的E的会计M1有效。

- 订单B创建于21.01,但是细分M1在20.01有变化,所以材料责任F是有效的

-order C创建于01.03,但是材料M1在26.02更改,因此Materialsponsible G有效

你能帮我解决一下这个问题吗?

由于

    CREATE TABLE [dbo].[Saleorder1](
    [Saleorder] nvarchar (20) NULL,
    [Datecreated] date NULL,
    [Material]  nvarchar (20) NULL,    )
INSERT INTO Saleorder1 (Saleorder,Datecreated,Material)
VALUES ('A','2016-01-01','M1'),
('B','2016.01.21','M1'),
('C','2016.03.01','M1')


    CREATE TABLE [dbo].[Material2](
    [Material] nvarchar(20) NULL,
    [Changedon] date NULL,
    [Materialresponsible]  nvarchar(20) NULL,)
INSERT INTO Material2
VALUES ('M1','2016-01-01','E'),
('M1','2016-01-20','F'),
('M1','2016-02-26','G')

1 个答案:

答案 0 :(得分:0)

如果您使用的是SQL Server 2012+,则可以使用LEAD功能获取上述结果

架构:

CREATE TABLE #Saleorder1(
[Saleorder] nvarchar (20) NULL,
[Datecreated] date NULL,
[Material]  nvarchar (20) NULL,    )


INSERT INTO #Saleorder1 (Saleorder,Datecreated,Material)
VALUES ('A','2016-01-01','M1'),
('B','2016.01.21','M1'),
('C','2016.03.01','M1')


CREATE TABLE #Material2(
[Material] nvarchar(20) NULL,
[Changedon] date NULL,
[Materialresponsible]  nvarchar(20) NULL,)

INSERT INTO #Material2
VALUES ('M1','2016-01-01','E'),
('M1','2016-01-20','F'),
('M1','2016-02-26','G')

现在选择LEAD功能,如下所示

SELECT S.Saleorder, S.Datecreated, M.Material,M.Materialresponsible 
FROM #Saleorder1 S
INNER JOIN (

SELECT Material ,Changedon  ,Materialresponsible
,ISNULL( LEAD(Changedon) OVER(ORDER BY (SELECT 1)),GETDATE()) Changedon_To_Dte  
FROM #Material2

)M ON S.Material = M.Material 
AND S.Datecreated BETWEEN M.Changedon AND M.Changedon_To_Dte

结果将是

+-----------+-------------+----------+---------------------+
| Saleorder | Datecreated | Material | Materialresponsible |
+-----------+-------------+----------+---------------------+
| A         | 2016-01-01  | M1       | E                   |
| B         | 2016-01-21  | M1       | F                   |
| C         | 2016-03-01  | M1       | G                   |
+-----------+-------------+----------+---------------------+

如果您使用的是较低版本的SQL Server。

--CTE for SNO Generation
;WITH CTE AS(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) SNO
,Material,Changedon,Materialresponsible 
FROM #Material2
)

--CTE2 for generating Changedon_To_Dte by SELF Joining
,CTE2 AS (
SELECT C1.Material,C1.Changedon,C1.Materialresponsible
, ISNULL(C2.Changedon, GETDATE()) AS Changedon_To_Dte
FROM CTE C1
LEFT JOIN CTE C2 ON C1.SNO+1 = C2.SNO 
)

SELECT S.Saleorder, S.Datecreated, C2.Material,C2.Materialresponsible  
FROM #Saleorder1 S
INNER JOIN CTE2 C2 ON S.Material = C2.Material 
AND S.Datecreated BETWEEN C2.Changedon AND C2.Changedon_To_Dte