60

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
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 で問題なく動作し、速度の低下はほとんどありません (ビューなしで元のサブクエリ select を実行する場合と比較して)。

于 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

これを回避するには、使用するサブクエリに対して個別の 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 に答える
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 に答える
4

サブクエリごとにビューを作成するのが道です。魔法のように機能しました。

于 2013-04-11T22:17:09.517 に答える