2010-04-15 50 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

相關問題