Domanda

In MySQL 5.0 perché si verifica il seguente errore quando si tenta di creare una vista con una subquery nella clausola FROM?

  

ERRORE 1349 (HY000): SELECT di View contiene una sottoquery nella clausola FROM

Se questa è una limitazione del motore MySQL, perché non hanno ancora implementato questa funzione?

Inoltre, quali sono alcune buone soluzioni per questa limitazione?

Esistono soluzioni alternative che funzionano per qualsiasi subquery nella clausola FROM o esistono query che non possono essere espresse senza utilizzare una subquery nella clausola FROM?


Una query di esempio (è stata sepolta in un commento):

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
È stato utile?

Soluzione

La query nel tuo commento non può essere scritta semplicemente come:

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

Ciò dovrebbe anche aiutare con i problemi di velocità noti con le subquery in MySQL

Altri suggerimenti

Ho avuto lo stesso problema. Volevo creare una vista per mostrare le informazioni dell'anno più recente, da una tabella con record dal 2009 al 2011. Ecco la query originale:

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

Schema della soluzione:

  1. crea una vista per ogni subquery
  2. sostituisci le sottoquery con quelle viste

Ecco la query della soluzione:

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;

Funziona benissimo su mysql 5.0.45, senza troppe penalità di velocità (rispetto all'esecuzione la sottoquery originale seleziona senza alcuna vista).

Sembra essere un problema noto.

http://dev.mysql.com/doc/ refman / 5.1 / it / senza nome-views.html

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

Molte query IN possono essere riscritte come join (esterni a sinistra) e un IS (NOT) NULL di qualche tipo. per esempio

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

può essere riscritto come

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

o

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

può essere

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

creare una vista per ogni sottoquery è la strada da percorrere. Ha funzionato come un fascino.

Puoi aggirare il problema creando una VISTA separata per qualsiasi subquery che desideri utilizzare e poi unisciti a quella nella VISTA che stai creando. Ecco un esempio: http://blog.gruffdavies.com/2015/01/25/a-neat-mysql-hack-to-create-a-view-with-subquery-in-the-from-clause/

Questo è abbastanza utile poiché molto probabilmente vorrai riutilizzarlo comunque e ti aiuta a mantenere il tuo SQL DRY.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top