Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在子查询中引用外部查询的表_Sql_Mysql - Fatal编程技术网

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

Sql 在子查询中引用外部查询的表,sql,mysql,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

是否可以使用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或将EXTER WHERE子句拉入子查询来实现同样的效果,但我需要自动生成SQL,并且由于各种其他原因,无法使用这两种方法

更新:抱歉,这个问题导致了一些混乱:第一个查询只是一个工作示例,用于演示我不需要的内容


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

我认为这不起作用,因为您在联接中引用派生表“c”


但是,您可以去掉WHERE p.user=u.id,并在派生表中替换为GROUP BY p.user,因为ON c.user=u.id将具有相同的效果。

这不是您想要的吗

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子句明确地对用户进行筛选。

此解决方案适用于postgresql。
您可以使用postgresql中提供的侧向联接。下面是如何在查询中使用它

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';

这是你可以使用的参考资料

这可能更好:

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

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';

这就是你如何在被接受的答案上展开的方法

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####
是否可以使用MySQL在子查询中引用外部查询

是的,这是绝对可能的。MySQL 8.0.14及以上版本:

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

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

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';

相关阅读:

Thx获取答案。但您的查询会做其他事情:它会统计所有用户,而不管加入日期如何。编辑:抱歉,看起来我忘记了内部组。如果子查询需要用户表中的一些不同的非id列来进行计数,该怎么办?这两个连接都是必需的,用于不同的目的-更新了问题,我想我仍然不明白。你根本不需要中间的WHERE子句,因为C和U之间的连接过滤掉了所有没有帖子的用户,并且正确地记录了基于用户ID的记录。我更新了帖子以反映我的意思。+1你是对的,那是我的错误,oedo速度更快,但为什么更新2?sql将解析派生表“c”,并获得所有用户ID及其post计数的完整列表。c.user=u.id上的连接将只返回满足u上的joinDate约束的用户。您可以使用postgresql中提供的横向连接-这对MySQL有何帮助?对于我们所有从谷歌来的人来说,这个问题匹配了90%的问题,除了平台。我也是为postgresql而来的:P
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';