在子查询中引用外部查询的表

时间:2010-04-15 13:08:58

标签: sql mysql

是否可以在MySQL子查询中引用外部查询?我知道有一些的情况,这是可能的:

SELECT *
FROM table t1
WHERE t1.date = (
    SELECT MAX(date)
    FROM table t2
    WHERE t2.id = t1.id
);

但我想知道这样的事情是否可行:

SELECT u.username, c._postCount
FROM User u
INNER JOIN (
    SELECT p.user, COUNT(*) AS _postCount
    FROM Posting p
    --# This is the reference I would need:
    WHERE p.user = u.id
    GROUP BY p.user
) c ON c.user = u.id
WHERE u.joinDate < '2009-10-10';

我知道我可以使用GROUP BY或通过将外部WHERE子句拉入子查询来实现相同的目标,但我需要这个用于自动生成SQL,并且不能使用其他任何替代方法的原因。

更新:抱歉,这个问题引起了一些困惑:第一个查询只是一个工作示例,用于演示我需要的内容。

更新2 :我需要u.id = p.user比较:第一个计算在“2009-10-10”之前加入的用户,而另一个是关联的加入条件表格行正确。

8 个答案:

答案 0 :(得分:18)

我认为这不起作用,因为你引用派生表'c'作为连接的一部分。

但是,你可以取出WHERE p.user = u.id,然后用派生表中的GROUP BY p.user替换,因为ON c.user = u.id会产生相同的效果。

答案 1 :(得分:18)

这不是你想要的吗?

SELECT u.username, c._postCount
FROM User u
INNER JOIN (
    SELECT p.user, COUNT(*) AS _postCount
    FROM Posting p
    GROUP BY p.user    
) c ON c.user = u.id
WHERE u.joinDate < '2009-10-10';

这将起作用的原因是连接本身的性质将过滤用户。您不需要在用户上明确过滤WHERE子句。

答案 2 :(得分:0)

非常接近...

WHERE t1.date = ( 
    SELECT MAX(date) 

更改为

WHERE t1.date IN ( 
    SELECT MAX(date) 

由于您的查询执行MAX(),因此它总是只返回一个日期...因为您的子选择具有唯一ID的过滤器,所以它应该为您提供所需的内容。

答案 3 :(得分:0)

这可能更好:

SELECT u.username,
(SELECT COUNT(*) FROM Posting WHERE user = u.id) as _postCount
FROM User u WHERE u.joinDate < '2009-10-10';

答案 4 :(得分:0)

这会很好

SELECT u.id as userid,u.username, c._postCount
FROM User u
INNER JOIN (
    SELECT p.user, COUNT(*) AS _postCount
    FROM Posting p
    --# This is the reference I would need:
    WHERE p.user = userid
    GROUP BY p.user
) c ON c.user = u.id
WHERE u.joinDate < '2009-10-10';

答案 5 :(得分:0)

这是您如何扩展已接受的答案

SELECT u.username, c._postCount
FROM User u
INNER JOIN (
    SELECT p.user, COUNT(*) AS _postCount
    FROM Posting p
    --# This is the reference I would need:
    --WHERE p.user = u.id ####REMOVE THIS####
    GROUP BY p.user
) c ON c.user = u.id
WHERE u.joinDate < '2009-10-10'
AND c.user = u.id -- ####ADD THIS####

答案 6 :(得分:0)

<块引用>

是否可以在 MySQL 的子查询中引用外部查询?

是的,绝对有可能。 MySQL 8.0.14 及更高版本:

<块引用>

13.2.11.9 Lateral Derived Tables

派生表通常不能在同一 FROM 子句中引用(依赖)前面表的列。 从 MySQL 8.0.14 开始,派生表可以定义为横向派生表,以指定允许此类引用。

SELECT u.username, c._postCount
FROM User u,
LATERAL (
    SELECT p.user, COUNT(*) AS _postCount
    FROM Posting p
    --# This is the reference I would need:
    WHERE p.user = u.id  
    GROUP BY p.user
) c
WHERE u.joinDate < '2009-10-10';

和缩小版本(删除不必要的分组):

SELECT u.username, c._postCount
FROM User u,
LATERAL (
    SELECT COUNT(*) AS _postCount
    FROM Posting p
    WHERE p.user = u.id  
) c
WHERE u.joinDate < '2009-10-10';

相关阅读:CROSS/OUTER APPLY in MySQL

答案 7 :(得分:-1)

此解决方案适用于postgresql。 您可以使用postgresql中提供的 LATERAL JOIN 。以下是在查询中使用它的方法。

SELECT u.username, c._postCount
FROM User u
INNER JOIN LATERAL (
    SELECT p.user, COUNT(*) AS _postCount
    FROM Posting p
    WHERE p.user = u.id
    GROUP BY p.user
) c ON c.user = u.id
WHERE u.joinDate < '2009-10-10';

这是您可以使用的参考。 https://medium.com/kkempin/postgresqls-lateral-join-bfd6bd0199df