我想计算两个表的内容增量 - @i
和@j
:
DECLARE @i TABLE (
[Id] [int] NOT NULL,
[Modified] [int] NOT NULL
)
DECLARE @j TABLE (
[Id] [int] NOT NULL,
[Code] [char](1) NOT NULL,
[Exported] [int] NOT NULL
)
delta应该只包含一列 - Id
,并按以下方式计算:
Id
来自@i
或@j
或两者(即FULL JOIN
)@i.Id
中找不到@j
或找不到@j.Code = 'D'
,@i.Id
,则会@i.Id
。{/ li>
@j
和@j.Exported < @i.Modified
中找到@i.Id
,则会@j.Code <> 'D'
。{/ li>
@j.Id
中找不到@i
和@j.Id
,则会SELECT COALESCE(i.Id, j.Id) Id
FROM @i i
FULL JOIN (SELECT * FROM @j WHERE Code <> 'D') j ON i.Id = j.Id
WHERE j.Exported IS NULL OR i.Modified IS NULL OR (j.Exported < i.Modified)
。这是我附带的SQL:
INSERT INTO @i VALUES (1,0),(2,0)
INSERT INTO @j VALUES (1,'D',1),(2,'C',1)
例如:
1
增量为SELECT COALESCE(i.Id, j.Id) Id
FROM @i i
FULL JOIN @j j ON Code <> 'D' AND i.Id = j.Id
WHERE j.Exported IS NULL OR i.Modified IS NULL OR (j.Exported < i.Modified)
。
我的问题是 - 我可以通过消除嵌套的select语句来简化这个SQL查询吗?
我试过这个:
1
但它产生两行 - 1
和Id
。请参阅here。
修改
伙计们,我故意提供一个非常简单的例子来证明这个问题。实际上,查询更复杂,键实际上是复合键,delta的结果不是简单的{{1}},而是更多。但问题是一样的。
答案 0 :(得分:0)
您应该能够使用案例陈述来评估这些条件。我不确定我是否涵盖了所有的边缘情况,但这里的逻辑很快转换成一个案例:
DECLARE @i TABLE (
[Id] [int] NOT NULL,
[Modified] [int] NOT NULL
)
DECLARE @j TABLE (
[Id] [int] NOT NULL,
[Code] [char](1) NOT NULL,
[Exported] [int] NOT NULL
)
INSERT INTO @i values (1,0)
insert into @i values (2,0)
INSERT INTO @j VALUES (1,'D',1)
insert into @j values (2,'C',1)
--The delta should contain just one column - Id and be calculated like this:
--Any Id in the result is coming from @i or @j or both (i.e. FULL JOIN)
--If @i.Id is not found in @j or found, but @j.Code = 'D', then @i.Id is taken.
--If @i.Id is found in @j and @j.Exported < @i.Modified, then @i.Id is taken.
--If @j.Code <> 'D' and @j.Id is not found in @i, then @j.Id is taken.
select [Id] = max(case
when j.Code = 'D' then i.Id
when j.Id is not null and j.Exported < i.Modified then i.Id
when j.Code <> 'D' and i.Id is null then j.Id
else -1 -- ??
end)
from @i i
left
join @j j on i.Id = j.Id
答案 1 :(得分:0)
了解案例陈述不适合您的申请,我可以建议:
-- 1. Any Id in the result is coming from @i or @j or both (i.e. FULL JOIN)
-- 2. If @i.Id is not found in @j or found, but @j.Code = 'D', then @i.Id is taken.
-- 3. If @i.Id is found in @j and @j.Exported < @i.Modified, then @i.Id is taken.
-- 4. If @j.Code <> 'D' and @j.Id is not found in @i, then @j.Id is taken
SELECT COALESCE(i.Id, j.Id) Id
FROM @i AS i
FULL JOIN @j AS j ON i.Id = j.Id
WHERE
(i.Id IS NOT NULL AND
( -- #2
j.Id IS NULL OR j.Code = 'D' OR
-- #3
(j.Exported IS NOT NULL AND j.Exported < i.Modified))
)
-- #4
OR (i.Id IS NULL AND j.Code <> 'D');