MySQL'变量'在CASE中不可用

时间:2011-08-10 19:00:56

标签: mysql mysql-error-1054

基本问题是 - 我试图在我的WHERE CASE语句中使用子查询的计数作为变量,但它似乎不允许我使用它。当我在WHERE区域中放置SELECT COUNT(id)...语句时,我有点工作,但是 - 如果我这样做,我将不得不包括它3-4次而不是只有一次如果我可以把它放在SELECT。

以下是解释我的问题的修改示例查询。这不是我正在使用的确切查询,但它提供了与我更长/更复杂的查询相同的错误:

错误:

[Err] 1054 - 'where子句'

中的未知列'matched_sections'

查询:

SELECT
    articles.id,
    (SELECT COUNT(id) FROM site_areas_site_sections WHERE
        site_areas_site_sections.site_area_id = 8) AS matched_sections
FROM
    articles
LEFT JOIN
    articles_site_sections ON articles_site_sections.article_id = articles.id
LEFT JOIN
    site_areas_site_sections ON articles_site_sections.site_section_id = 
    site_areas_site_sections.site_section_id
WHERE
    (CASE
        WHEN
            matched_sections > 0
        THEN
           site_sections.id = site_areas_site_sub_sections.site_sub_section_id
        END
)

3 个答案:

答案 0 :(得分:1)

问题是当MySQL开始解析你的查询时,SELECT子句是最后要分析的位。因此,当它通过WHERE子句时,matched_sections尚不存在(因为尚未查看SELECT子句。

快速浏览一下,你可以试试这样的东西(虽然我觉得有人会想出一些更优雅的东西):

SELECT
    articles.id,
    matched_sections.count
FROM
    articles
LEFT JOIN
    articles_site_sections ON articles_site_sections.article_id = articles.id
LEFT JOIN
    site_areas_site_sections ON articles_site_sections.site_section_id = 
    site_areas_site_sections.site_section_id, 
(SELECT COUNT(id) as count FROM site_areas_site_sections WHERE
        site_areas_site_sections.site_area_id = 8) matched_sections
WHERE
    (CASE
        WHEN
            matched_sections.count > 0
        THEN
           site_sections.id = site_areas_site_sub_sections.site_sub_section_id
        END
)

答案 1 :(得分:1)

由于处理SQL语句元素的顺序,在评估matched_sections子句时未定义WHERE

您可能希望将计数预先填充到变量中,并在查询中使用它。

DECLARE matched_sections INT;

SET matched_sections = (SELECT COUNT(id) 
                            FROM site_areas_site_sections 
                            WHERE site_areas_site_sections.site_area_id = 8);

答案 2 :(得分:0)

正如您已经被告知的那样,错误与WHERE子句对您实际选择的值一无所知的事实有关,因为它在SELECT子句之前被评估。

通常,您可以通过将整个查询用作派生表来解决此问题,在这种情况下,matched_sections别名可用于外部查询:

SELECT
  id,
  matched_section
FROM (
  SELECT
      articles.id,
      (SELECT COUNT(id) FROM site_areas_site_sections WHERE
          site_areas_site_sections.site_area_id = 8) AS matched_sections
  FROM
      articles
  LEFT JOIN
      articles_site_sections ON articles_site_sections.article_id = articles.id
  LEFT JOIN
      site_areas_site_sections ON articles_site_sections.site_section_id = 
      site_areas_site_sections.site_section_id
) s
WHERE
  CASE
    WHEN matched_sections > 0
    THEN …
  END

如果原始条件包含对不打算检索的列的引用,则需要将它们添加到派生表的选择列表中,以便在外部查询的条件中使用它们。

如果子查询与主查询不相关(并且不在您的示例中),@ Joe和@Dirk的解决方案可能是比上述建议更好的选择。