获得先前集合中存在的值但后续集合中缺失的值

时间:2016-08-24 17:20:41

标签: sql sql-server sql-server-2008 tsql

我无法理解为什么这么难以实现!

我想要做的就是从之前的结果集中检索一个值,该值在同一个表中的以后的结果集中不存在。

这就是我想要实现的目标:

select b.Id
from table a
where
    not exists
        (select b.Id from table b where b.Id = a.Id and
        b.time = (select max(time) from table where time < a.time))

我知道这在语法上不正确,难以访问b.Id同时保持对其他集time的引用,这是我尝试的每种形式的问题,例如使用{ {1}}。我也尝试了外连接到同一个表,试图找到丢失的Id,但无济于事。

我发现很容易找到后一组中存在缺失行的ID,而不是之前的,但不是相反。

我正在使用SQL Server 2008R2。

修改

这很难用,所以我举一个例子:

except

所以我期望的结果是行:

{5,98,13:00}和{9,97,11:00}因为之前的集合中缺少ID。请注意,时间来自后一组,以显示 时间设置中缺少它们。

4 个答案:

答案 0 :(得分:0)

我会考虑使用group byhaving执行此操作。如果我理解正确:

select t.id
from table t
group by t.id
having max(t.time) < @LaterTime and 
       sum(case when t.time >= @EarlierTime then 1 else 0 end) > 0;

答案 1 :(得分:0)

尝试使用表变量。

DECLARE @table1 TABLE (column1, column2, column3)
DECLARE @table2 TABLE (column1, column2, column3)

SELECT INTO @table1 (column1, column2, column3)
VALUES
FROM IntendedTable
WHERE Date < DesiredDate

SELECT INTO @table1 (column1, column2, column3)
VALUES
FROM IntendedTable
WHERE Date > DesiredDate

SELECT * 
FROM @table1
WHERE NOT EXISTS (SELECT * FROM @table2)

上述内容在语法上并不正确,但可能是我采取的方法。

答案 2 :(得分:0)

Ids只有一次,第一次

select * 
from table
where id in (
  select t1.id 
  from table t1
  group by t1.id
  having count(distinct t1.time) = 1 )
 and time = (select min(t2.time) from table t2)

修改 在OP注释之后,id

的所有缺失行都超过了min
  select  id,time
  from (
     select t1.id,t2.time
     from
      (select distinct id from table ) t1
     cross join 
      (select distinct time  from table) t2     
     except
      select distinct id,time
      from table     
   ) tt  
   where time > (select min(t3.time) from table t3 where t3.id=tt.id)

答案 3 :(得分:0)

我认为这就是你想要的。给出了预期的结果。

CREATE TABLE #T (PK INT , ID INT , [TIME] TIME)

INSERT INTO #T
SELECT 1 ,100 , '13:00' UNION ALL
SELECT 2 ,99  , '13:00' UNION ALL
SELECT 3 ,100 , '11:00' UNION ALL
SELECT 4 ,99  , '11:00' UNION ALL
SELECT 5 ,98  , '11:00' UNION ALL
SELECT 6 ,100 , '10:00' UNION ALL
SELECT 7 ,99  , '10:00' UNION ALL
SELECT 8 ,98  , '10:00' UNION ALL
SELECT 9 ,97  , '10:00'

;WITH R
AS
(
    SELECT DENSE_RANK() OVER (ORDER BY T1.TIME DESC) RANK,*
    FROM #T T1
)

SELECT DISTINCT R1.PK, R1.ID, R2.TIME 
FROM R R1
INNER JOIN R R2  ON R1.RANK = R2.RANK + 1  
WHERE 
NOT EXISTS
(
    SELECT ID, TIME  FROM R R2 WHERE R1.RANK = R2.RANK + 1  AND R1.ID = R2.ID 
)