2008-10-15 134 views
53

在MySQL 5.0中,爲什麼在嘗試使用FROM子句中的子查詢創建視圖時發生以下錯誤?MySQL:在FROM子句限制中查看子查詢

ERROR 1349(HY000):視圖的SELECT包含在FROM子句中

如果這是MySQL引擎的限制子查詢,那麼爲什麼我沒有他們實現了這個功能了嗎?

此外,這種限制有哪些好的解決方法?

是否有任何解決方法適用於FROM子句中的任何子查詢,還是有一些查詢無法在FROM子句中使用子查詢來表示嗎?


示例查詢(被埋葬在一個評論):

SELECT temp.UserName 
FROM (SELECT u1.name as UserName, COUNT(m1.UserFromId) as SentCount 
     FROM Message m1, User u1 
     WHERE u1.uid = m1.UserFromId 
     Group BY u1.name HAVING SentCount > 3) as temp 
+0

感謝您發佈此信息。我通常避免在MySQL中的意見。在一個邊緣案例上工作,試圖聯合fk表 - 將它們鎖在一個視圖中。現在這個。多麼痛苦 - 所有這些對子查詢的限制?準備好轉向不同的引擎。 – eggmatters 2016-02-26 17:37:13

回答

17

無法在您的評論的查詢剛寫如:

SELECT u1.name as UserName from Message m1, User u1 
    WHERE u1.uid = m1.UserFromID GROUP BY u1.name HAVING count(m1.UserFromId)>3 

這也應該與子查詢已知的速度問題幫助在MySQL

+0

謝謝,我沒有意識到你可以在沒有SELECT中的聚合函數的情況下執行GROUP BY。所以他們在MySQL的FROM子句中不允許子查詢的原因之一是因爲速度問題? – Daniel 2008-10-15 20:01:16

5

這似乎是一個已知的問題。

http://dev.mysql.com/doc/refman/5.1/en/unnamed-views.html

http://bugs.mysql.com/bug.php?id=16757

許多查詢可以重新寫爲(左外)連接和某種形式的IS(NOT)NULL。例如

SELECT * FROM FOO WHERE ID IN (SELECT ID FROM FOO2) 

可以重新寫爲

SELECT FOO.* FROM FOO JOIN FOO2 ON FOO.ID=FOO2.ID 

SELECT * FROM FOO WHERE ID NOT IN (SELECT ID FROM FOO2) 

可以

SELECT FOO.* FROM FOO 
LEFT OUTER JOIN FOO2 
ON FOO.ID=FOO2.ID WHERE FOO.ID IS NULL 
+0

但是,你將如何重寫FROM子句中的查詢?舉例來說,我怎麼可能重寫此查詢?: SELECT temp.UserName FROM(SELECT 作爲u1.name用戶名,COUNT(m1.UserFromId)作爲SentCount FROM消息M1,用戶U1 WHERE u1.uid = M1。 UserFromId Group BY u1.name HAVING SentCount> 3 )as temp – Daniel 2008-10-15 19:48:31

+0

我不認爲你可以,但你可以創建第二個視圖並從中選擇,而不是使用子選擇,據我所知。如果你不介意存儲過程,你也可以使用臨時表(假設有足夠的MySQL版本)。 – Nikki9696 2008-10-15 21:18:22

+0

或者,正如我注意到的,格蘭特的解決方案可能適合你。 – Nikki9696 2008-10-15 21:20:07

74

我有同樣的問題。我想創建一個視圖來顯示最近一年的信息,從表記錄從2009年到2011年這裏的原始查詢:

  1. 創建一個視圖:

    SELECT a.* 
    FROM a 
    JOIN ( 
        SELECT a.alias, MAX(a.year) as max_year 
        FROM a 
        GROUP BY a.alias 
    ) b 
    ON a.alias=b.alias and a.year=b.max_year 
    

    的解決方案概述每個子查詢

  2. 人士的意見

替換子查詢下面是該解決方案的查詢:

CREATE VIEW v_max_year AS 
    SELECT alias, MAX(year) as max_year 
    FROM a 
    GROUP BY a.alias; 

CREATE VIEW v_latest_info AS 
    SELECT a.* 
    FROM a 
    JOIN v_max_year b 
    ON a.alias=b.alias and a.year=b.max_year; 

它在mysql 5.0.45上正常工作,沒有太多的速度損失(與執行 原始子查詢選擇而沒有任何視圖相比)。

3

爲每個子查詢創建一個視圖是要走的路。讓它像魅力一樣工作。