检查表是否包含具有相同ID的条目,并比较这些条目的值

时间:2016-07-05 09:13:58

标签: sql sql-server

我有一个包含FileIDStateDate列的表格 它包含每个操作,可以使用该文件完成 例如,如果我创建一个文件,它会插入一个带有新FileId的条目,日期,创建日期和状态"创建"。如果我删除此文件,它会创建一个包含文件的fileId的新条目,设置日期,删除时间以及设置状态"删除" 所以它看起来像这样

FileID | Date     | State
----------------------------
FileA  | 1.1.2016 | Created
FileA  | 3.1.2016 | Deleted
FileB  | 1.1.2016 | Created

我想要的是获取在特定日期存在的所有文件。所以如果我说,我想要所有文件,它们存在于2.1.2016,它应该返回我的例子中文件A和文件B的第一行。如果我在4.1.2016查找所有文件,它应该返回FileB

我该如何进行这种比较? 我正在尝试像

这样的东西
SELECT *
FROM TableA
WHERE FileId IN     (SELECT FileId FROM TableA WHERE Date <= [DATE] AND State = 'Created')
  AND FileId NOT IN (SELECT FileId FROM TableA WHERE Date > [DATE] AND State = 'Deleted')

5 个答案:

答案 0 :(得分:0)

试试这个

SELECT * FROM TableA
WHERE Date >= [DATE] AND State = 'Created' AND FileId NOT IN (SELECT FileId FROM TableA WHERE Date >= [DATE] AND State = 'Deleted')

答案 1 :(得分:0)

对于SQL Server 2012+,您需要按FileID分组,然后使用窗口函数来获取最新状态:

select FileID, 
    first_value(State) over (partition by FileID order by Date desc) as LastAction
from TableA
where Date <= [DATE]
group by FileID
having first_value(State) over (partition by FileID order by Date desc) <> 'Deleted'

SQL Server 2008不支持first_value(),您需要在子查询中使用row_number()来解决此问题:

select FileID
from (
    select FileID,
        State,
        row_number() over (partition by FileID order by Date desc) as LastActionRow
    from TableA
    where Date <= [DATE]
)
where LastActionRow = 1
  and State <> 'Deleted'

答案 2 :(得分:0)

在下面的查询中,我们首先选择在给定日期之前创建的记录。然后返回到同一个表,查找在给定日期之前删除文件的时间。

如果文件尚未删除,则已删除记录的左连接将返回NULL。

SELECT a.*
FROM TableA a

-- Join to TableA, looking for 'Deleted' records before the requested date
LEFT JOIN TableA b ON 
    a.FileID = b.FileID AND b.state = 'Deleted' AND b.Date <= [Date]

WHERE
    -- Find files that were created before the requested date
    a.State = 'Created'
    AND a.Date <= [DATE]
    -- and have not been deleted before the requested date
    AND b.FileID IS NULL

请注意,这假设每个fileID只有一个“已创建”和一个“已删除”记录。

答案 3 :(得分:0)

试试这个

SELECT A.* from TableA A
INNER JOIN 
(SELECT FileID, MIN([Date]) minDate FROM TableA GROUP BY FileID ) TM
ON A.FileID= TM.FileID and A.Date = TM.minDate

答案 4 :(得分:0)

首先感谢您提出的所有建议,但我现在想出了一个解决方案,至少在我的情况下有效。

解决方案是:

Select * FROM TableA
WHERE State = 'Created' AND Date <= [DATE]
AND FileId NOT IN (SELECT FileID FROM TableA WHERE State = 'Deleted' AND Date <= [DATE])