2010-04-15 85 views
33

是否可以使用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生成,并且由于各种其他原因,不能使用其他替代方法。

UPDATE:对不起,这个问题导致了一些困惑:第一个查询只是一个工作的例子,来证明什么,我需要。

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

+1

为什么更新2? sql将解析派生表'c'并获取所有用户标识符及其后期计数的完整列表。那么'ON c.user = u.id'的连接只会返回满足'u'上的joinDate约束的用户。 – oedo 2010-04-15 16:19:54

+0

哦,你绝对正确,看起来像是我的错误。我会把你的commant标记为接受的答案:) – soulmerge 2010-04-15 16:47:47

+0

谢谢,很高兴我能帮到:) – oedo 2010-04-15 23:28:25

回答

14

我认为这是行不通的,因为你引用了派生表'c'作为连接的一部分。但是,您可以取出WHERE p.user = u.id,并在派生表中替换为GROUP BY p.user,因为ON c.user = u.id将具有相同的效果。

+0

Thx的答案。但是你的查询会做一些其他的事情:它会统计所有用户,而不管加入日期。 *编辑*:对不起,看起来我已经忘记了内部组 – soulmerge 2010-04-15 13:25:46

0

非常接近......

WHERE t1.date = ( 
    SELECT MAX(date) 

变化

WHERE t1.date IN ( 
    SELECT MAX(date) 

由于您的查询做了一个MAX(),它总是返回只有一个日期......因为你的子选择具有过滤器上的唯一ID,它应该给你你想要的。

+2

这不是OP的问题,而且使用=而不是IN也可以。 – oedo 2010-04-15 13:13:52

+1

oedo的权利 - 更新的问题,以澄清 – soulmerge 2010-04-15 15:19:51

14

这不是你所追求的吗?

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子句。

+0

这两个连接都是强制性的,服务于不同的目的 - 更新了问题 – soulmerge 2010-04-15 15:19:15

+0

我想我还是不明白。根本不需要中间的where子句,因为c和u之间的连接会过滤掉没有帖子的所有用户,并根据用户标识正确关联记录。我更新了这篇文章以反映我的意思。 – Jeremy 2010-04-15 16:35:53

+0

+1你说得对,那是我的错误(尽管oedo速度更快) – soulmerge 2010-04-15 16:49:13

-1

此解决方案适用于postgresql。 您可以使用LATERAL JOIN,它在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'; 

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

相关问题