Pregunta

En MySQL 5.0, ¿por qué ocurre el siguiente error al intentar crear una vista con una subconsulta en la cláusula FROM?

  

ERROR 1349 (HY000): SELECT de View contiene una subconsulta en la cláusula FROM

Si esta es una limitación del motor MySQL, ¿por qué no han implementado esta función todavía?

Además, ¿cuáles son algunas buenas soluciones para esta limitación?

¿Existen soluciones alternativas que funcionen para cualquier subconsulta en la cláusula FROM o hay algunas consultas que no se pueden expresar sin usar una subconsulta en la cláusula FROM?


Una consulta de ejemplo (se enterró en un comentario):

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
¿Fue útil?

Solución

No se pudo escribir la consulta en tu comentario como:

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

Eso también debería ayudar con los problemas de velocidad conocidos con las subconsultas en MySQL

Otros consejos

Tuve el mismo problema. Quería crear una vista para mostrar información del año más reciente, a partir de una tabla con registros de 2009 a 2011. Aquí está la consulta original:

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

Esquema de la solución:

  1. crear una vista para cada subconsulta
  2. reemplazar las subconsultas con esas vistas

Aquí está la consulta de la solución:

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;

Funciona bien en mysql 5.0.45, sin mucha penalización de velocidad (en comparación con la ejecución la selección original de la subconsulta sin ninguna vista).

Parece ser un problema conocido.

http://dev.mysql.com/doc/ refman / 5.1 / es / unnamed-views.html

http://bugs.mysql.com/bug.php?id=16757

Muchas consultas IN se pueden volver a escribir como uniones (izquierda externa) y un IS (NO) NULL de algún tipo. por ejemplo

SELECT * FROM FOO WHERE ID IN (SELECT ID FROM FOO2)

se puede reescribir como

SELECT FOO.* FROM FOO JOIN FOO2 ON FOO.ID=FOO2.ID

o

SELECT * FROM FOO WHERE ID NOT IN (SELECT ID FROM FOO2)

puede ser

SELECT FOO.* FROM FOO 
LEFT OUTER JOIN FOO2 
ON FOO.ID=FOO2.ID WHERE FOO.ID IS NULL

crear una vista para cada subconsulta es el camino a seguir. Lo tengo funcionando como un encanto.

Puedes solucionar esto creando una VISTA por separado para cualquier subconsulta que quieras usar y luego unirte a ella en la VISTA que estás creando. Aquí hay un ejemplo: http://blog.gruffdavies.com/2015/01/25/a-neat-mysql-hack-to-create-a-view-with-subquery-in-the-from-clause/

Esto es bastante útil ya que probablemente querrás reutilizarlo de todos modos y te ayuda a mantener tu SQL DRY.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top