是否可以在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”之前加入的用户,而另一个是关联的加入条件表格行正确。
答案 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';
答案 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