webdevqa.jp.net

MySQL:FROM句の制限のサブクエリで表示

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
57
Daniel

コメントのクエリを次のように書くことはできませんでした。

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のサブクエリに関する既知の速度の問題にも役立つはずです。

18
Grant Limberg

同じ問題がありました。 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で正常に動作します。

これは既知の問題のようです。

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
5
Nikki9696

各サブクエリのビューを作成する方法があります。それは魅力のように機能しました。

4
Dexin Wang

これを回避するには、使用するサブクエリごとに個別のVIEWを作成し、作成するVIEWのサブクエリに結合します。以下に例を示します: http://blog.gruffdavies.com/2015/01/25/a-neat-mysql-hack-to-create-a-view-with-subquery-in-the-from-句/

とにかく再利用したいので、これは非常に便利で、SQL DRYを維持するのに役立ちます。

4
Gruff