sql、外连接

发布于 2024-11-09 10:06:57 字数 189 浏览 0 评论 0原文

我有两个表,通过外部联接链接。主表和辅助表之间的关系是 1 到 [0..n]。辅助表包括一个时间戳列,指示添加记录的时间。我只想检索主表中每行的辅助表的最新记录。由于其他表也是 SELECT 的一部分,因此我必须在主表上使用 group by。但无法使用“having”子句,因为该辅助表不是该组的一部分。

如何在不进行多次查询的情况下做到这一点?

I have two tables, linked with an outer join. The relationship between the primary and secondary table is a 1 to [0..n]. The secondary table includes a timestamp column indicating when the record was added. I only want to retrieve the most recent record of the secondary table for each row in the primary. I have to use a group by on the primary table due to other tables also part of the SELECT. There's no way to use a 'having' clause though since this secondary table is not part of the group.

How can I do this without doing multiple queries?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

月寒剑心 2024-11-16 10:06:57

为了性能,尽量减少接触表的次数

选项 1,OUTER APPLY

SELECT *
FROM
   table1 a
  OUTER APPY
  (SELECT TOP 1 TimeStamp FROM table2 b
   WHERE a.somekey = b.somekey ORDER BY TimeStamp DESC) x

选项 2,聚合

SELECT *
FROM
  table1 a
  LEFT JOIN
  (SELECT MAX(TimeStamp) AS maxTs, somekey FROM table2
   GROUP BY somekey) x ON a.somekey = x.somekey

注意:每个表都被提及一次,没有相关子查询

For performance, try to touch the table least times

Option 1, OUTER APPLY

SELECT *
FROM
   table1 a
  OUTER APPY
  (SELECT TOP 1 TimeStamp FROM table2 b
   WHERE a.somekey = b.somekey ORDER BY TimeStamp DESC) x

Option 2, Aggregate

SELECT *
FROM
  table1 a
  LEFT JOIN
  (SELECT MAX(TimeStamp) AS maxTs, somekey FROM table2
   GROUP BY somekey) x ON a.somekey = x.somekey

Note: each table is mentioned once, no correlated subqueries

绝對不後悔。 2024-11-16 10:06:57

类似于:

SELECT a.id, b.* 
FROM table1 a
INNER JOIN table2 b ON b.parentid = a.id
WHERE b.timestamp = (SELECT MAX(timestamp) FROM table2 c WHERE c.parentid = a.id)

如果要显示 table1 中 ID 的行而 table2 中没有任何匹配项,请使用 LEFT JOIN 而非 INNER JOIN 。

Something like:

SELECT a.id, b.* 
FROM table1 a
INNER JOIN table2 b ON b.parentid = a.id
WHERE b.timestamp = (SELECT MAX(timestamp) FROM table2 c WHERE c.parentid = a.id)

Use LEFT JOIN instead of INNER JOIN if you want to show rows for IDs in table1 without any matches in table2.

空城缀染半城烟沙 2024-11-16 10:06:57
select *
from table1 left outer join table2 a on
   table1.id = a.table1_id
where
  not exists (select 1 from table2 b where a.table1_id = b.table1_id and b.timestamp > a.timestamp)
select *
from table1 left outer join table2 a on
   table1.id = a.table1_id
where
  not exists (select 1 from table2 b where a.table1_id = b.table1_id and b.timestamp > a.timestamp)
樱花坊 2024-11-16 10:06:57

我知道的最快的方法是这样的:

SELECT
  A.*,
  B.SomeField
FROM
  Table1 A
  INNER JOIN (
    SELECT
      B1.A_ID,
      B1.SomeField
    FROM
      Table2 B1
      LEFT JOIN Table2 B2 ON (B1.A_ID=B2.A_ID) AND (B1.TimeStmp < B2.TimeStmp)
    WHERE
      B2.A_ID IS NULL
  ) B ON B.A_ID = A.ID

The quickest way I know of is this:

SELECT
  A.*,
  B.SomeField
FROM
  Table1 A
  INNER JOIN (
    SELECT
      B1.A_ID,
      B1.SomeField
    FROM
      Table2 B1
      LEFT JOIN Table2 B2 ON (B1.A_ID=B2.A_ID) AND (B1.TimeStmp < B2.TimeStmp)
    WHERE
      B2.A_ID IS NULL
  ) B ON B.A_ID = A.ID
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文