【问题标题】:MySQL 'variable' not available in CASEMySQL“变量”在 CASE 中不可用
【发布时间】:2011-08-10 19:00:56
【问题描述】:

基本问题是 - 我试图在我的 WHERE CASE 语句中使用子查询的计数作为变量,但它似乎不允许我使用它。当我将 SELECT COUNT(id)... 语句放在 WHERE 区域时,我已经让它有点工作了,但是 - 如果我这样做,我将不得不包含它 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
)

【问题讨论】:

  • 除了不存在(在评估 WHERE 子句时)matched_section 列之外,您的 CASE 表达式似乎还有另一个问题。它引用了一个在 FROM 子句中找不到的表 (site_areas_site_sub_sections)。
  • @Andriy M,上面的 sql 是“解释我的问题的修改示例查询”,他可能只是忘记添加/排除其他必要的位。

标签: mysql mysql-error-1054


【解决方案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
)

【讨论】:

    【解决方案2】:

    由于 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);
    

    【讨论】:

      【解决方案3】:

      正如您已经被告知的那样,该错误与 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 的解决方案可能比上述建议更好。

      【讨论】:

        猜你喜欢
        • 2016-06-08
        • 2021-04-01
        • 1970-01-01
        • 2011-12-13
        • 1970-01-01
        • 2013-05-15
        • 1970-01-01
        • 2022-06-29
        • 1970-01-01
        相关资源
        最近更新 更多