MySQL“变量”不适用于案例

发布于 2024-11-29 05:03:26 字数 942 浏览 1 评论 0原文

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

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

错误:

[Err] 1054 - 'where Clause' 中的未知列 '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
)

Basic problem is - I'm trying to use a sub-query's count as a variable in my WHERE CASE statement, but it doesn't appear to let me use it. I've got it somewhat working when I put the SELECT COUNT(id)... statement in the WHERE area, but - if I do that, I'll have to include it 3-4 different times instead of just once if I can put it in the SELECT.

Below is a modified example query that explains my problem. It's not the exact query I'm using, but it gives the same error as my much-longer/more complicated query:

Error:

[Err] 1054 - Unknown column 'matched_sections' in 'where clause'

Query:

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
)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小傻瓜 2024-12-06 05:03:26

问题是当 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
)

The problem is when MySQL starts to parse out your query, the SELECT clause is the last bit to be analyzed. So when it's going through the WHERE clause, matched_sections doesn't yet exists (because the SELECT clause has yet to be looked at.

Just a quick look at it, you can try something like this (although I think someone will be able to come up with something a little more elegant):

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
)
静赏你的温柔 2024-12-06 05:03:26

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

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

DECLARE matched_sections INT;

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

Due to the order in which the elements of a SQL statement are processed, matched_sections is not defined at the time the WHERE clause is evaluated.

You might want to prepopulate the count into a variable, and use that in your query.

DECLARE matched_sections INT;

SET matched_sections = (SELECT COUNT(id) 
                            FROM site_areas_site_sections 
                            WHERE site_areas_site_sections.site_area_id = 8);
舞袖。长 2024-12-06 05:03:26

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

As you have already been told, the error is related to the fact that the WHERE clause knows nothing about the values you are actually selecting, because it is evaluated before the SELECT clause.

In general, you can solve this problem by using the entire query as a derived table, in which case the matched_sections alias becomes available to the outer query:

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

If your original condition contains references to columns that are not meant to be retrieved, you will need to add them to the derived table's selection list so you can use them in the outer query's condition.

In cases where the subquery is not correlated with the main query (and it isn't in your example), the solutions by @Joe and by @Dirk are possibly better options than the above suggestion.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文