如何使用表1中的列值遍历table2

时间:2018-10-09 00:52:54

标签: sql sql-server sql-server-2016

我有两个表,表1和表2。

Table1 :
ID   Type   StartDate    EndDate   Units
AAA  1      4/3/2018     4/7/2018   1
AAA  1      4/8/2018     4/21/2018  1
AAA  1      1/8/2017     2/6/2017   2
AAA  1      1/1/2017     1/7/2017   2
BBB  2      7/16/2017    7/22/2017  1 
BBB  2      8/1/2017     8/1/2017   1

Table 2:
  ID   Type   StartDate     EndDate 
 AAA   1      01/02/2017    01/17/2017
 AAA   1      01/02/2017    01/17/2017
 AAA   1      01/02/2017    01/17/2017
 AAA   1      01/02/2017    01/17/2017
 AAA   1      02/01/2017    02/28/2017
 AAA   1      02/01/2017    02/28/2017
 AAA   1      02/01/2017    02/28/2017
 AAA   1      02/01/2017    02/28/2017
 AAA   1      02/01/2017    02/28/2017
 AAA   1      04/03/2018    04/03/2018
 AAA   1      04/10/2018    04/10/2018
 BBB   2      07/20/2017    07/21/2017
 BBB   2      08/01/2017    09/01/2017

我必须查看(table2。Table1开始日期和结束日期之间的开始日期)或(table2结束日期在table1开始日期和结束日期之间的),然后循环并标记Table2 = Y以表示该范围内table1中的单位数。 / p>

My Expected output is :
ID   Type   StartDate     EndDate        Flag
 AAA   1      01/02/2017    01/17/2017   Y 
 AAA   1      01/02/2017    01/17/2017   Y
 AAA   1      01/02/2017    01/17/2017   Y 
 AAA   1      01/02/2017    01/17/2017   Y
 AAA   1      02/01/2017    02/28/2017   N
 AAA   1      02/01/2017    02/28/2017   N
 AAA   1      02/01/2017    02/28/2017   N 
 AAA   1      02/01/2017    02/28/2017   N
 AAA   1      02/01/2017    02/28/2017   N
 AAA   1      04/03/2018    04/03/2018   Y 
 AAA   1      04/10/2018    04/10/2018   Y
 BBB   2      07/20/2017    07/21/2017   Y
 BBB   2      08/01/2017    09/01/2017   Y

我必须考虑这两个表的ID,类型和日期范围。我必须对照table1检查table2的Table2开始日期和Table2结束日期。 谁能帮我解决这个循环吗?

这是代码。

SELECT ROW_NUMBER() OVER(
ORDER BY id, StartDate, EndDate) AS AID, StartDate
id , units, StartDate, EndDate, [Type], Flag
INTO #tempA
FROM #table1;

SELECT ROW_NUMBER() OVER( ORDER BY ID, StartDate, EndDate, Type,Flag) AS CID,
 ID, StartDate, EndDate, Type, Flag
INTO #tempC
FROM #table2;


    SELECT a.AID
         , c.CID
         , a.ID
    INTO #tempCombined
    FROM
         #tempA a CROSS JOIN #tempC c
    WHERE a.ID = c.ID
          AND a.Type = c.Type
          AND ((c.StartDate BETWEEN a.StartDate AND a.EndDate) 
               OR (c.EndDate BETWEEN a.StartDate AND a.EndDate))
    ORDER BY a.Aid , c.CID

DECLARE @List TABLE
    (
         Aid    INT, 
         Cid    INT, 
         ID Varchar(50)
    )

DECLARE @count INT, @countMax INT, @Unit INT

SET @count = 1

SELECT @countMax = MAX(aid)
FROM #tempA

-- get @List which CIDs to be proved
WHILE @count <=  @countMax
    BEGIN

        SELECT @Unit = units
        FROM #tempA
        WHERE aid = @count

        SET ROWCOUNT @Unit

        INSERT INTO @List (Aid , Cid , ID)
           SELECT ac.AID , ac.CID , ac.ID
           FROM #tempCombined ac 
           WHERE ac.AID = @count 
                 AND ac.CID not in (select cid from @List where ID=ac.ID)
        order by cid,ID
        SET ROWCOUNT 0
        SET @count+=1
    END

UPDATE c
  SET 
      c.UpdateFlag = 'Y'
FROM #tempC c 
INNER JOIN @List cl
ON c.CID = cl.Cid

SELECT *
FROM #tempC

2 个答案:

答案 0 :(得分:0)

为此,您不需要循环,只需正确的联接即可。

select 
   t2.*
   ,Flag = case when t1.Units is not null then 'Y' else 'N' end --or whatever logic
from Table2 t2
left join Table1 t1 on 
    t1.ID = t2.ID
and t1.Type = t2.Type
and(
       (t2.StartDate between t1.StartDate and t1.EndDate) 
    or (t2.EndDate between t1.Startdate and t1.EndDate)
   )

答案 1 :(得分:0)

一种方法可能是遍历表2,逐行循环并将其与表1进行比较。除非表的大小较小,否则此方法可能会出现性能问题。

CREATE TABLE T4
([ID] varchar(3), [Type] int, [StartDate] datetime, [EndDate] datetime, [Flag] varchar(1))
; 
WHILE (SELECT count(*) FROM t2) > 0
BEGIN   
   select top(1) * into t3 from t1 where (((select top(1) startDate from t2) between t1.startDate and t1.endDate)  or ((select top(1) endDate from t2) between t1.startDate and t1.endDate)) and t1.units>0
   IF (select count(*) from t3) > 0
       insert into t4 ([ID] , [Type] , [StartDate] , [EndDate] , [Flag]) (select top(1) *,Flag='Y' from t2);
   ELSE
       insert into t4 ([ID] , [Type] , [StartDate] , [EndDate] , [Flag]) (select top(1) *,Flag='N' from t2);
   delete top(1) from t2;
   update t1 set units = units-1 where t1.startDate=(select startdate from t3) and t1.endDate=(select enddate from t3) and t1.type=(select type from t3) and t1.id=(select id from t3);
   drop table t3;
END