关于嵌套查询和自然连接的 SQL 查询

Posted

技术标签:

【中文标题】关于嵌套查询和自然连接的 SQL 查询【英文标题】:SQL query about Nested query and NATURAL JOIN 【发布时间】:2012-01-10 21:21:12 【问题描述】:

我有三张桌子。 第一个表是活动,第二个是成员,最后一个是消息。 活动有一个名为 Members_ID 的外键,主键是 Activity_ID。 成员的主键是 Members_ID。 消息记录了Activity_ID 和Members_ID。 我想搜索活动 NATURAL JOIN 成员,我需要一个新的列数 Message的message_ID与Activity_ID相同。

自然加入:

SELECT*
    FROM Activities 
        NATURAL JOIN Members 
    WHERE Activities.Members_ID = Members.Members_ID;

COUNT(message_ID):

SELECT COUNT(message_ID) 
    FROM Message 
    WHERE Activity_ID = 123;

问题是: 如何将以上两件事一起搜索? 我想要一个表有具有相同Activities.Members_ID 的Activity NATURAL JOIN 成员 和一个虚拟列,它是来自表 Message 的 COUNT(message_ID)。

【问题讨论】:

我建议避免自然连接;明确说明您的连接谓词是一种更好的做法,IMO。 【参考方案1】:
WITH MessageTallies 
     AS
     (
      SELECT Activity_ID, COUNT(message_ID) AS tally
        FROM Message
       GROUP 
          BY Activity_ID
     )
SELECT *
  FROM Activities 
       NATURAL JOIN Members 
       NATURAL JOIN MessageTallies
UNION CORRESPONDING
SELECT *, 0 AS tally
  FROM Activities 
       NATURAL JOIN Members 
 WHERE Activity_ID NOT IN (SELECT Activity_ID FROM MessageTallies):

【讨论】:

【参考方案2】:

也许您希望使用相关子查询,如下所示:

SELECT *, (SELECT COUNT(message_ID) FROM Message WHERE Activity_ID = a.Activity_ID AND Members_ID = m.Members_ID) AS Message_Count
    FROM Activities AS a
        NATURAL JOIN Members AS m
    WHERE a.Members_ID = m.Members_ID;

但是,我会避免使用自然连接语法:

SELECT *, (SELECT COUNT(message_ID) FROM Message WHERE Activity_ID = a.Activity_ID AND Members_ID = m.Members_ID) AS Message_Count
    FROM Activities AS a
        JOIN Members AS m on a.Members_ID = m.Members_ID;

【讨论】:

谢谢,但是(SELECT COUNT(message_ID) FROM Message WHERE Activity_ID = a.Activity_ID AND Members_ID = m.Members_ID 不是我需要的正确结果。因为不同的成员可能会插入相同的活动。消息表可能有来自不同成员但相同活动 ID 的两条记录。 SELECT *, (SELECT COUNT(message_ID) FROM Message WHERE Activity_ID = a.Activity_ID) AS Message_Count FROM 活动作为 JOIN 成员 AS m on a.Members_ID = m.Members_ID; 正确答案。感谢 Tim Lehner 和大家。【参考方案3】:
SELECT a.Activity_ID, a.col1, a.col2, ..., a.colx, COUNT(mg.message_ID)
    FROM Activities a
        INNER JOIN Members m
            ON a.Members_ID = m.Members_ID
        INNER JOIN Message mg
            ON a.Activity_id = m.Activity_ID 
    GROUP BY a.Activity_ID, a.col1, a.col2, ..., a.colx;

【讨论】:

我需要 Activity_ID 来自加入 m。 Activity_ID = 123 只是示例。 @YuChunLin 查看我编辑的答案。这更像你想要的吗? 谢谢乔。但它看起来不像我想要的。 它将是一个新表,其中包含活动、自然联接成员 m 和嵌套查询或从消息表中添加新列 COUNT(m.message_ID) 的东西。 COUNT(m.message_ID) m.message_ID 在消息表中而不在成员表中。感谢您的帮助。

以上是关于关于嵌套查询和自然连接的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

嵌套查询与连接查询的区别是啥

带有连接的 SQL 查询以获取嵌套的对象数组

Mybatis 的嵌套查询与嵌套结果的区别

Mybatis 的嵌套查询与嵌套结果的区别

关于SQL DELETE嵌套子查询问题

oracle 嵌套查询 子查询 自连接 等值连接条件