60

在 MySQL 5.0 中,为什么在 FROM 子句中尝试使用子查询创建视图时会出现以下错误?

ERROR 1349 (HY000): View 的 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
4

5 回答 5

84

我有同样的问题。我想创建一个视图来显示最近一年的信息,从一个包含 2009 年到 2011 年记录的表中。这是原始查询:

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

解决方案概要:

  1. 为每个子查询创建一个视图
  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 上运行良好,没有太大的速度损失(与执行没有任何视图的原始子查询选择相比)。

于 2010-08-19T09:48:50.257 回答
18

你的查询不能写成:

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 中子查询的已知速度问题

于 2008-10-15T19:54:19.647 回答
5

这似乎是一个已知问题。

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

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

许多 IN 查询可以重写为(左外)连接和某种 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
于 2008-10-15T19:38:01.940 回答
5

您可以通过为要使用的任何子查询创建单独的 VIEW 来解决此问题,然后在您正在创建的 VIEW 中加入该视图。这是一个例子:http: //blog.gruffdavies.com/2015/01/25/a-neat-mysql-hack-to-create-a-view-with-subquery-in-the-from-clause/

这非常方便,因为您很可能希望重用它并帮助您保持 SQL DRY。

于 2015-01-27T09:45:27.977 回答
4

为每个子查询创建一个视图是要走的路。让它像魅力一样工作。

于 2013-04-11T22:17:09.517 回答