Sql 这可以转换为基于集合的查询吗?
我有一个疑问:Sql 这可以转换为基于集合的查询吗?,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,我有一个疑问: if OBJECT_ID('tempdb..#tempA') is not null drop table #tempA create table #tempA ( tempid varchar(5), tempdate smalldatetime ) declare @loopdate smalldatetime set @loopdate = '4/2/2013' while (@loopdate <= '4/28/2013') begin
if OBJECT_ID('tempdb..#tempA') is not null drop table #tempA
create table #tempA
(
tempid varchar(5),
tempdate smalldatetime
)
declare @loopdate smalldatetime
set @loopdate = '4/2/2013'
while (@loopdate <= '4/28/2013')
begin
--Purpose is to get IDs not in TableB for each date period
insert into #tempA (tempid, tempdate)
select storeid, @loopdate
from
(
select tableAid
from tableA
except
select tableBid
from tableB
where tableBdate = @loopdate
) as idget
set @loopdate = DATEADD(day, 1, @loopdate)
end
您可以在条件子句中包括日期范围,如下所示:
insert into #tempA (tempid, tempdate)
select tableAid
from tableA
except
select tableBid
from tableB
where tableBdate >= '4/2/2013' and tableBdate <= '4/28/2013';
仍然是一个循环,但可能更有效一点
while (@loopdate <= '4/28/2013')
begin
--Purpose is to get IDs not in TableB for each date period
insert into #tempA (tempid, tempdate)
select storeid, @loopdate
from
(
select tableAid
from tableA
left join tableB
on tableB.tableBid = tableA.tableAid
and tableB.tableBdate = @loopdate
where tableB.tableBid is null
) as idget
set @loopdate = DATEADD(day, 1, @loopdate)
end
这需要一些工作,但可能会让你一路设置
;WITH Days
as
(
SELECT cast('4/2/2013' AS datetime ) as 'Day'
UNION ALL
SELECT DATEADD(DAY, +1, Day) as 'Day'
FROM Days
where [DAY] <= '4/28/2013'
)
SELECT tableA.tableAid, Days.[Day]
from Days
left join tableB
on tableB.tableBdate = Days.[Day]
full join tableA
on tableB.tableBid = tableA.tableAid
where tableB.tableBid is null
这取决于tableA是否有日期,如果没有,则:
WITH DateList(DateDay) AS
(
SELECT CAST('2013-04-28' AS DATETIME)
UNION ALL
SELECT DATEADD(DAY, DATEDIFF(DAY,0,DATEADD(DAY, -1, DateDay)),0)
FROM DateList
WHERE DateDay between '2013-04-03' and '2013-04-28'
)
SELECT DISTINCT
tableAid
, DateDay
FROM DateList
cross join #tableA a
left join #tableB b
on tableAid = b.tableBid
and b.tableBdate = DateDay
where
b.tableBid is null
ORDER BY
DateDay ASC
我很确定可以,但是你能发布源数据和期望的最终结果的示例吗?你不是在为tempdate插入一个值。这是行不通的。你怎么做可能是最好的办法。集合解决方案需要生成这组日期。左连接真的比除外连接更有效吗?只是想知道。@dotn00b除了使用索引外,还能使用什么?
insert into #tempA (tempid, tempdate)
select tableAid, tableAdate
from tableA
except
select tableBid,tableBdate
from tableB
where tableBdate >= '4/2/2013' and tableBdate <= '4/28/2013';
WITH DateList(DateDay) AS
(
SELECT CAST('2013-04-28' AS DATETIME)
UNION ALL
SELECT DATEADD(DAY, DATEDIFF(DAY,0,DATEADD(DAY, -1, DateDay)),0)
FROM DateList
WHERE DateDay between '2013-04-03' and '2013-04-28'
)
SELECT DISTINCT
tableAid
, DateDay
FROM DateList
cross join #tableA a
left join #tableB b
on tableAid = b.tableBid
and b.tableBdate = DateDay
where
b.tableBid is null
ORDER BY
DateDay ASC