1

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
)
2
  • Apart from the non-existent (at the time of evaluating the WHERE clause) matched_section column, your CASE expression seems to have another problem. It references a table that is found nowhere in the FROM clause (site_areas_site_sub_sections). Commented Aug 10, 2011 at 19:16
  • 3
    @Andriy M, the above sql is "a modified example query that explains my problem" and he probably just forgot to in/exclude the other necessary bits. Commented Aug 10, 2011 at 19:18

3 Answers 3

1

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
)
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.