Sql server 简化某个SQL Server查询

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

我想计算两个表的内容增量-@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:

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');