Sql 如何从审核表中找到最近使用";修改的列值;左自排除联接“;?

Sql 如何从审核表中找到最近使用";修改的列值;左自排除联接“;?,sql,tsql,outer-join,Sql,Tsql,Outer Join,我有以下表格设计(它是不变的,而且很糟糕): 表1:“ID”:id1、id2 将每个id1映射到一个或多个id2值 表2“审计”:id2,时间戳,唯一id 将每个id2映射到其更改的审核跟踪。unique_id保证表中的每一行都是唯一的 目标:针对id1的每个不同值;选择一行;根据表2最新修改了包含单个id2值(表1中映射到id1的值中的值)的值 我曾尝试过中概述的“左自排除连接”方法,但不太清楚如何使其工作。我的问题如下: select i1.id1, a2.id2 from ids i1

我有以下表格设计(它是不变的,而且很糟糕):

表1:“ID”:id1、id2

将每个id1映射到一个或多个id2值

表2“审计”:id2,时间戳,唯一id

将每个id2映射到其更改的审核跟踪。unique_id保证表中的每一行都是唯一的

目标:针对id1的每个不同值;选择一行;根据表2最新修改了包含单个id2值(表1中映射到id1的值中的值)的值

我曾尝试过中概述的“左自排除连接”方法,但不太清楚如何使其工作。我的问题如下:

select i1.id1, a2.id2
from   ids i1
right join audit a1 on i1.id2=a1.id2
left join ids i2 on i1.id1=i2.id1
left outer join audit a2 on i2.id2=a2.id2
where a1.timestamp < a2.timestamp
and a1.unique_id!=a2.unique_id
-- and a1.id2 is null
此数据的预期结果集:

id1   id2   explanation
1     11    id2=11 last modified at 104, id2=12 at 103.
2     23    Only 1 row. That case tripped my query too.
澄清:我知道这个问题可以通过相关子查询解决,而无需使用左自排除联接。我对如何做到这一点不感兴趣,我感兴趣的是我的左自排除联接查询出了什么问题。

修改后的答案:

查询1

SELECT
      audit1.*
FROM (
  select data.id1 as data_id, audit.id2 as fk, audit.timestamp, audit.unique_id
  from audit
  INNER JOIN ids data ON audit.id2 = data.id2
) as audit1
LEFT OUTER JOIN (
  select data.id1 as data_id, audit.id2 as fk, audit.timestamp, audit.unique_id
  from audit
  INNER JOIN ids data ON audit.id2 = data.id2
  ) AS audit2 ON audit1.data_id = audit2.data_id 
             AND audit1.timestamp < audit2.timestamp
             AND audit1.unique_id <> audit2.unique_id
WHERE audit2.data_id is null
| data_id | fk | timestamp | unique_id |
|---------|----|-----------|-----------|
|       1 | 11 |       104 |     10001 |
|       2 | 23 |       101 |     10004 |

“链接SO”问题中的自排除联接方法的工作方式是,设置从一个表到自身的左外部联接,以便不是所需行的每一行都至少有一个链接,而所需行则没有。所以不是

left outer join audit a2 on i2.id2=a2.id2
你需要像这样的东西

left outer join audit a2 on a1.id2=a2.id2 AND a1.timestamp < a2.timestamp
a1上的左外部联接审核a2。id2=a2.id2和a1.timestamp 这意味着不是给定ID的最高时间戳的每一行都将链接到至少一个其他a2行,但最高时间戳(您想要的)不会。然后使用WHERE A2.id2 IS NULL子句删除所有不需要的行


请注意,随着具有相同id的项目数量的增加,将创建(并忽略)更多中间数据。五个项目的最低时间戳为4行,下一个为3行,以此类推。大小为阶乘(n-1),可以很快变大。

我恳请您不要提供等于“仅子查询方法”的答案/注释。我的主要目标是理解为什么“左自排除连接”不起作用。我不知道我是否理解了你的问题,但是你能在第一次连接时移除“右”方向来测试它吗?也许这对你有帮助。@GustavoAdolfo-是的。没有效果(事实上,原始版本没有“正确的”连接,这是我试图解决的问题)需要查看一些数据(文本表,而不是图像)好的,现在知道了(修改我的答案)。我确实需要查看数据(谢谢),并且我使用了一些列别名使其对我更有意义。对不起,这是错误的。它返回3行而不是2行。我将测试数据(以及示例fiddle URL)编辑到正确的位置。但是,我试图为每个id1值获取一行,而不是为每个id2值获取一行(从id1映射为1-N)。是的,示例数据在审计的id2中有11、12和23=每个审计1行。id2除非11pm干扰了我的头脑,否则11、12和23 ad id2值。不是id1。Id1值为1和2。我也在问题中加入了预期的结果集。我想我让步了,专栏的命名让我头疼。
left outer join audit a2 on i2.id2=a2.id2
left outer join audit a2 on a1.id2=a2.id2 AND a1.timestamp < a2.timestamp