相关子查询的MySql范围问题

时间:2010-03-12 20:26:58

标签: sql mysql scope correlated-subquery

我正在使用这个Mysql查询,它有效:

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     

结果是:

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

它工作正确,但只有当我将查询硬编码到我想要的ID时(37)。 我想让它适用于m3allem表中的所有条目,所以我试试这个:

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

我收到错误:

  

'where'中的未知列'm.id'   条款“

为什么呢? 从MySql手册:

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

所以......当子查询在SELECT部分​​时,这不起作用吗?我没有读到任何关于此的内容。

有谁知道吗?我该怎么办?我花了很长时间来构建这个查询...我知道它是一个怪物查询,但它在单个查询中得到了我想要的东西,而且我非常接近它的工作!

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:6)

您只能将一个级别关联起来。

使用:

   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 = ?

答案 1 :(得分:1)

错误的原因是未定义子查询m。它稍后在外部查询中定义。