2010-03-12 7 views
5

sto avendo questa query MySQL, Funziona:MySql problema scoping con subquery correlate

SELECT 
    nom 
    ,prenom 
    ,(SELECT GROUP_CONCAT(category_en) FROM 
      (SELECT DISTINCT category_en FROM categories c WHERE id IN 
       (SELECT DISTINCT category_id FROM m3allems_to_categories m2c WHERE m3allem_id = 37) 
      ) cS 
    ) categories 
    ,(SELECT GROUP_CONCAT(area_en) FROM 
      (SELECT DISTINCT area_en FROM areas c WHERE id IN 
       (SELECT DISTINCT area_id FROM m3allems_to_areas m2a WHERE m3allem_id = 37) 
      ) aSq 
    ) areas 
FROM m3allems m 
WHERE m.id = 37  

Il risultato è:

nom    prenom  categories    areas 
Man    Multi  Carpentry,Paint,Walls Beirut,Baalbak,Saida 

Funziona correclty, ma solo quando ho hardcode nella query l'id che voglio (37). Voglio farlo funzionare per tutte le voci della tabella m3allem, quindi provo questo:

SELECT 
    nom 
    ,prenom 
    ,(SELECT GROUP_CONCAT(category_en) FROM 
      (SELECT DISTINCT category_en FROM categories c WHERE id IN 
       (SELECT DISTINCT category_id FROM m3allems_to_categories m2c WHERE m3allem_id = m.id) 
      ) cS 
    ) categories 
    ,(SELECT GROUP_CONCAT(area_en) FROM 
      (SELECT DISTINCT area_en FROM areas c WHERE id IN 
       (SELECT DISTINCT area_id FROM m3allems_to_areas m2a WHERE m3allem_id = m.id) 
      ) aSq 
    ) areas 
FROM m3allems m 

e ottengo un errore:

Unknown column 'm.id' in 'where clause'

Perché? Dal manuale MySql:

13.2.8.7. Correlated Subqueries 
[...] 
Scoping rule: MySQL evaluates from inside to outside. 

Così ... fare questo non funziona quando la subquery è in una sezione SELEZIONE? Non ho letto nulla a riguardo.

Qualcuno sa? Cosa dovrei fare? Mi ci è voluto molto tempo per costruire questa query ... So che è una domanda mostruosa, ma ottiene quello che voglio in una singola query, e sono così vicino a farlo funzionare!

Qualcuno può aiutare?

risposta

6

È possibile correlare solo un livello in profondità.

Usa:

SELECT m.nom, 
      m.prenom, 
      x.categories, 
      y.areas 
    FROM m3allens m 
LEFT JOIN (SELECT m2c.m3allem_id, 
        GROUP_CONCAT(DISTINCT c.category_en) AS categories 
      FROM CATEGORIES c 
      JOIN m3allems_to_categories m2c ON m2c.category_id = c.id 
     GROUP BY m2c.m3allem_id) x ON x.m3allem_id = m.id 
LEFT JOIN (SELECT m2a.m3allem_id, 
        GROUP_CONCAT(DISTINCT a.area_en) AS areas 
      FROM AREAS a 
      JOIN m3allems_to_areas m2a ON m2a.area_id = a.id 
     GROUP BY m2a.m3allem_id) y ON y.m3allem_id = m.id 
    WHERE m.id = ? 
+0

Funziona! Grazie mille! Non sapevo che puoi correlare solo un livello in profondità. – Rolf

1

La ragione per l'errore è che nella sottoquery m non è definito. È definito più tardi nella query esterna.