【问题标题】:sql, outer joinsql,外连接
【发布时间】:2011-05-21 18:45:39
【问题描述】:

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

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

【问题讨论】:

  • 你能给出完整的结构,以及你现在遇到的任何不工作的查询吗?
  • 您绝对应该向我们提供您的查询,或者至少是它的概要,以便我们更好地了解您实际在说什么。

标签: sql join outer-join


【解决方案1】:

为了提高性能,尽量少碰桌子

选项 1,外部应用

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

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

【讨论】:

  • @declan:大部分,尤其是第二个
  • 我认为他的意思是“哪个 RDBMS?”答案是“MS SQL”。我不知道任何其他使用 APPLY 的 RDBMS。 Here 是一个很好的讨论。 Here 是 MS 文档。
【解决方案2】:

类似:

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。

【讨论】:

  • 我想你的意思是MAX(timestamp),获取最新的。
  • 使用 "select(max...)" 作为 WHERE 子句的一部分,这不适用于外连接(结果是它会返回 only 表 a 中的行在表 b 中也至少有一行。但是,我认为这很接近。我在 where 子句中添加了一个“或 b.timestamp=null”,它似乎可以工作。
  • @Steve Lopez:点了。对于LEFT JOIN,您必须将外部WHERE 更改为AND,以便在连接条件中应用子查询;这样,即使子查询没有产生任何行,外连接仍然会为这些情况产生结果。
【解决方案3】:
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)

【讨论】:

    【解决方案4】:

    我知道的最快的方法是:

    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
    

    【讨论】:

    • 这不是 table2 上的三角形 JOIN 最快的。
    • 嗯,这是 我 知道的最快的方法,或者至少对于包含第二个表中的字段的结果而言。
    猜你喜欢
    • 2021-01-31
    • 2021-09-02
    • 1970-01-01
    • 2010-12-06
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 2012-01-06
    相关资源
    最近更新 更多