我有两个表,表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
答案 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