Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL: View with Subquery in the FROM Clause Limitation

In MySQL 5.0 why does the following error occur when trying to create a view with a subquery in the FROM clause?

ERROR 1349 (HY000): View's SELECT contains a subquery in the FROM clause

If this is a limitation of the MySQL engine, then why haven't they implemented this feature yet?

Also, what are some good workarounds for this limitation?

Are there any workarounds that work for any subquery in the FROM clause or are there some queries that can not be expressed without using a subquery in the FROM clause?


An example query (was buried in a comment):

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 
like image 299
Daniel Avatar asked Oct 15 '08 19:10

Daniel


People also ask

Is it possible to include a subquery after FROM clause?

From clause can be used to specify a sub-query expression in SQL.

What are the limitations of subquery?

Subqueries cannot manipulate their results internally, that is, a subquery cannot include the order by clause, the compute clause, or the into keyword. Correlated (repeating) subqueries are not allowed in the select clause of an updatable cursor defined by declare cursor. There is a limit of 50 nesting levels.

Can I use limit in subquery MySQL?

Intention of using limit in subquery is so main query run on limited records fetched from subquery. And if we keep limit outside then it makes limit useless for subquery.

Can I use subquery in view?

Subqueries cannot be used in the FROM clause of a view. There is a general principle that you cannot modify a table and select from the same table in a subquery.


2 Answers

I had the same problem. I wanted to create a view to show information of the most recent year, from a table with records from 2009 to 2011. Here's the original query:

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 

Outline of solution:

  1. create a view for each subquery
  2. replace subqueries with those views

Here's the solution query:

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; 

It works fine on mysql 5.0.45, without much of a speed penalty (compared to executing the original sub-query select without any views).

like image 61
Json on Linux Apache MySQL Avatar answered Oct 12 '22 20:10

Json on Linux Apache MySQL


Couldn't your query just be written as:

SELECT u1.name as UserName from Message m1, User u1    WHERE u1.uid = m1.UserFromID GROUP BY u1.name HAVING count(m1.UserFromId)>3 

That should also help with the known speed issues with subqueries in MySQL

like image 30
Grant Limberg Avatar answered Oct 12 '22 20:10

Grant Limberg