当前位置:  开发笔记 > 编程语言 > 正文

MySQL:在FROM子句限制中使用子查询查看

如何解决《MySQL:在FROM子句限制中使用子查询查看》经验,为你挑选了3个好方法。

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

错误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

小智.. 80

我有同样的问题.我想创建一个视图来显示最近一年的信息,从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

解决方案概要:

    为每个子查询创建一个视图

    用这些视图替换子查询

这是解决方案查询:

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上工作正常,没有太多的速度惩罚(与执行没有任何视图的原始子查询选择相比).



1> 小智..:

我有同样的问题.我想创建一个视图来显示最近一年的信息,从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

解决方案概要:

    为每个子查询创建一个视图

    用这些视图替换子查询

这是解决方案查询:

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上工作正常,没有太多的速度惩罚(与执行没有任何视图的原始子查询选择相比).


备份失败,因为mysql根据其名称恢复视图,因此它将首先尝试恢复"v_latest_info"并因为"v_max_year"尚不存在而失败...

2> Grant Limber..:

您的评论中的查询无法写成:

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


*"您的评论中的查询无法写成......"*这引用了什么评论?

3> Nikki9696..:

这似乎是一个已知问题.

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

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有