2012-01-22 139 views
0

我必須選擇一個計數列,按兩個數據源中的日期分組。我將結果集作爲子查詢加入。然而,結果是假的。正如我所看到的,這個問題與JOIN .. ON條款有關。此查詢工作正常:連接子查詢的列範圍

SELECT id 
FROM pu a 
LEFT JOIN (
    SELECT 
     COUNT(pd.id) AS c_id1, 
     NULL AS c_id2, 
     LEFT(pd.start_date, 10) AS date, 
     pd.pid 
    FROM 
     p_d pd 
    **WHERE pd.pid = 111** 
    GROUP BY date 

    UNION 

    SELECT 
     NULL AS c_id1, 
     COUNT(pd.id) AS c_id2, 
     LEFT(pd.inactivation_date, 10) AS date, 
     pd.pid 
    FROM 
     p_d pd 
    **WHERE pd.pid = 111** 
    GROUP BY date 
) x 
ON x.pid = a.id; 

但是這一個(不WHERE子句)返回一個錯誤的結果集:

SELECT id 
FROM pu a 
LEFT JOIN (
    SELECT 
     COUNT(pd.id) AS c_id1, 
     NULL AS c_id2, 
     LEFT(pd.start_date, 10) AS date, 
     pd.pid 
    FROM 
     p_d pd 
    GROUP BY date 

    UNION 

    SELECT 
     NULL AS c_id1, 
     COUNT(pd.id) AS c_id2, 
     LEFT(pd.inactivation_date, 10) AS date, 
     pd.pid 
    FROM 
     p_d pd 
    GROUP BY date 
) x 
ON x.pid = a.id; 

很可能在不知何故加入子查詢使用a.id?現在是「未知專欄」。

+0

後一個結果有什麼問題?有點難以猜測你期待的結果。 –

+0

Joachim,第二個查詢僅返回帶有僞造數字的前3-4行(日期)。第一個返回所有的行(在這種情況下,〜80)與正確的計數。 – Eduard7

回答

2

在你的子查詢中,你使用pd.pid這樣的列作爲SELECT,它們不是GROUP BY的一部分,也沒有彙總。這樣的列被稱爲hidden,在標準的SQL中,這會給語法錯誤,但是mysql允許它,儘管它可以自由地從每個組中的任何行中選擇值。

如果限制你的設置爲WHERE pd.pid = 111組中的所有pd.pid值都是相同的,所以使用哪一行來獲取它並不重要,但是如果沒有WHERE,則pd.pid的值將是未定義(mysql可能會選擇可以最快獲取你的那個)。您還可以使用該未定義的pid作爲JOIN,因此您肯定會得到錯誤的結果。

http://dev.mysql.com/doc/refman/5.6/en/group-by-hidden-columns.html

很難但是說你應該如何重寫查詢,你不提供關於表的模式,什麼是你想實現的,什麼是你的表/列名的含義足夠的信息。

+0

這個答案啓發了我,我的整個做法都很糟糕。剛剛完成查詢翻新,謝謝。 – Eduard7