MySQL:FROM句の制限のサブクエリで表示
-
03-07-2019 - |
質問
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
解決
コメント内のクエリを次のように記述できませんでした:
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のサブクエリに関する既知の速度の問題にも役立つはずです
他のヒント
同じ問題がありました。 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で正常に動作しますが、速度のペナルティはあまりありません(実行と比較して ビューのない元のサブクエリ選択)。
既知の問題のようです。
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
各サブクエリのビューを作成する方法があります。チャームのように動作します。
この問題を回避するには、使用するサブクエリごとに個別の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を維持するのに役立ちます。