获取在特定日期之前创建且在该日期之后未引用的 ID

Posted

技术标签:

【中文标题】获取在特定日期之前创建且在该日期之后未引用的 ID【英文标题】:Getting IDs where created before a specific date and not referenced after that date 【发布时间】:2016-10-21 17:01:15 【问题描述】:

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

基本上,我正在尝试检索在指定日期之前创建的记录的 IDCreated 列)除非这条记录被另一个引用(@987654323 @ 列)在此日期之后创建。

(我打算在某个时候在存储过程中使用它,但暂时只使用一个变量)

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

+--------+---------+---------------+
|   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 不是(因此我也不会得到 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

【问题讨论】:

【参考方案1】:

你可以用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

【讨论】:

我可以扩展它以考虑 2 个不同的日期吗?假设我想要日期 [X] 之前的 ID,如果它们被引用,那么引用必须在日期 [Y] 之前创建? 当然..你可以做到。 抱歉,在我开始盲目地投入价值进行测试之前,请先确定一下。这是否只是第 6 行 @myDate 的使用变量 [X] 和第 5 行 @myDate 的新变量 [Y]? 是的,内部条件检查是否有任何 ref_id 具有较晚的日期,而外部条件是给定日期之前的 id。你可以相应地修改它。【参考方案2】:

已编辑:我意识到(在接受解决方案并重新阅读原始请求之后)您并没有要求在 t1 创建之后排除具有相关 t2 记录的 t1 记录,而是在“mydate”之后日期。我相应地更改了下面的查询(但是,我想 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(在指定日期之前),我将加入(如果存在)所有创建日期大于“mydate”且 ref_id 等于 t1.id 的案例。 在那之后,我说我不想要找到匹配项的行(即使用t2.id is null),从而使我得到所需的结果集。

至于对请求的最后添加(在要排除的记录中引用不同的“开始日期”),您只需将查询修改为:

 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

【讨论】:

以上是关于获取在特定日期之前创建且在该日期之后未引用的 ID的主要内容,如果未能解决你的问题,请参考以下文章

在特定日期之后获取唯一 ID 的 SQL 查询

查找每个 ID 的特定日期之前的最大日期和特定日期之后的最小日期 [关闭]

获取在特定日期创建和/或修改的存储过程列表?

对于特定的日期时间,在 [关闭] 之前和之后查找日期时间最近的记录

从两个表创建一个临时表,选择特定日期之前的最新日期

BigQuery - 在给定的时间点获取不同的值