获取在特定日期之前创建的ID,而不是在该日期之后引用的

时间:2016-10-21 17:01:15

标签: sql sql-server tsql

我正在尝试从查询中获取ID列表,该查询依赖于另一行中ID引用列和日期列中的值。

基本上,我正在尝试为指定日期(ID列)之前创建的记录检索Created,除非此记录被其他人引用(在此日期之后创建的RefID列。

(我计划在某些时候在sproc中使用它,但暂时只使用一个变量)

下面非常简单的示例表。为简单起见,遗漏了不相关的列。

+--------+---------+---------------+
|   ID   |  RefID  |    Created    |
+--------+---------+---------------+
|  123   |  NULL   |  2016-10-18   |
|  456   |  123    |  2016-10-20   |
|  789   |  NULL   |  2016-10-18   |
|  111   |  789    |  2016-10-18   |
+--------+---------+---------------+

所以在我上面的示例表中,如果我指定2016-10-19,我会得到ID 789和111。我不会得到123,因为虽然它是在2016-10-18之前创建的,但它被456引用而不是(因此我也不会得到456回复)。

我一直在摆弄加入的变化,但SQL绝对不是我的强项,所以我觉得我在圈子里跑,并且在那里追逐错误的解决方案!
到目前为止我有这个,我认为正在为我提供在特定日期之后引用的正确ID列表。我不太确定如何从我的主查询中排除这个列表...更不用说适当的主要查询是什么。

DECLARE @myDate datetime
SET @myDate = '2016-10-19'

SELECT t1.id
FROM MyDB.dbo.[myTable] AS t1
JOIN MyDB.dbo.[myTable] AS t2
ON t1.id = t2.ref_id
WHERE t1.id = t2.ref_id AND t2.created > @myDate

2 个答案:

答案 0 :(得分:2)

您可以使用not exists获取条件,以检查引用的ID是否在指定日期之后有一行。

SELECT id
FROM MyDB.dbo.[myTable] t1
WHERE NOT EXISTS (SELECT 1 FROM MyDB.dbo.[myTable] 
                  WHERE t1.id = ref_id 
                  AND created > @myDate) 
AND created < @myDate

Sample Demo

答案 1 :(得分:1)

  

已编辑:我意识到(在接受解决方案并重新阅读原始请求之后)您没有要求在创建t1之后排除具有相关t2记录的t1记录,但是在&#34之后;数值指明MyDate&#34;日期。我相应地在下面更改了我的查询(但是,我猜,vkp查询的表现也比我修改后的答案更好)。

我从您的查询开始,到达此提案:

 SELECT t1.id
   FROM MyDB.dbo.[myTable] AS t1
   LEFT JOIN MyDB.dbo.[myTable] AS t2
     ON t1.id = t2.ref_id and t2.created > @mydate
  WHERE t2.id is null AND t1.created < @mydate

因此,对于表t1(在指定日期之前),我加入(如果存在)所有创建日期大于&#34; mydate&#34;一,ref_id等于t1.id. 在那之后,我说我不想要找到匹配的行(这是t2.id is null的使用),从而留下了我想要的结果集。

至于请求的最后一次添加(具有不同的&#34;开始日期&#34;用于在要排除的记录中的引用),您只需要修改查询:

 SELECT t1.id
   FROM MyDB.dbo.[myTable] AS t1
   LEFT JOIN MyDB.dbo.[myTable] AS t2
     ON t1.id = t2.ref_id 
     and t2.created > @exclusionstartdate
  WHERE t2.id is null AND t1.created < @mydate