Sql server 简化某个SQL Server查询
我想计算两个表的内容增量-@I和@j: 增量应仅包含一个列Id,并按如下方式计算: 结果中的任何Id都来自@i或@j或两者,即完全连接 如果@i.Id未在@j或found中找到,但@j.Code='D',则取@i.Id。 如果在@j和@j.Exported<@i.Modified中找到@i.Id,则取@i.Id。 如果@i中未找到@j.Code'D'和@j.Id,则取@j.Id。 以下是我附带的SQL:Sql server 简化某个SQL Server查询,sql-server,Sql Server,我想计算两个表的内容增量-@I和@j: 增量应仅包含一个列Id,并按如下方式计算: 结果中的任何Id都来自@i或@j或两者,即完全连接 如果@i.Id未在@j或found中找到,但@j.Code='D',则取@i.Id。 如果在@j和@j.Exported
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)
三角洲是1
我的问题是-我可以通过消除嵌套的select语句来简化这个SQL查询吗
我试过这个:
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)
但它会产生两行-1和1。看
编辑
伙计们,我故意给出一个非常简单的例子来说明这个问题。实际上,查询更复杂,键实际上是复合键,增量的结果不是简单的Id,而是更多。但问题是相同的。您应该能够使用案例陈述来评估这些条件。我不确定我是否涵盖了你所有的边缘案例,但以下是你的逻辑很快转化为案例:
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. 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');
这不是我可以在实际应用中使用的东西。是的,结果很简单。谢谢
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. 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');