WHERE 子句在 CTE 之后找不到列?
WHERE clause does not find column after a CTE?
SQL 中的 CTE 和子查询的新功能。
我有 3 个表:
categories (category_code, category)
countries (country_code, country, continent)
businesses (business, year_founded, category_code, country_code)
目标是了解世界上最古老的企业。我使用了 CTE:
WITH bus_cat_cont AS (
SELECT business, year_founded, category, country,
continent
FROM businesses AS b
INNER JOIN categories AS c1
ON b.category_code = c1.category_code
INNER JOIN countries AS c2
ON b.country_code = c2.country_code
)
SELECT continent,
category,
COUNT(business) AS n
FROM bus_cat_cont
WHERE n > 5
GROUP BY continent, category
ORDER BY n DESC;
代码在没有 WHERE n > 5
的情况下也能正常工作。但是添加之后,我得到了错误:
column "n" does not exist
我意识到有一种更简单的方法可以在没有 CTE 的情况下获得我想要的输出。
但我想知道:为什么会出现此错误?
这可行:
WITH bus_cat_cont AS (
SELECT business, year_founded, category, country, continent
FROM businesses AS b
JOIN categories AS c1 ON b.category_code = c1.category_code
JOIN countries AS c2 ON b.country_code = c2.country_code
)
SELECT continent, category, count(business) AS n
FROM bus_cat_cont
-- WHERE n > 5 -- wrong
GROUP BY continent, category
HAVING count(business) > 5 -- right
ORDER BY n DESC;
output 列名称“n”在 WHERE
或 HAVING
子句中(尚)不可见。考虑 SQL 查询中的事件序列:
- Best way to get result count before LIMIT was applied
郑重声明,该结果与您宣布的 “看看世界上最古老的企业” 的目标没有明显联系。 year_founded
未在查询中使用。
您获得了企业中最常见的 continent/category 组合。
除此之外,可能更好:
SELECT co.continent, ca.category, n
FROM (
SELECT category_code, country_code, count(*) AS n
FROM businesses
GROUP BY 1, 2
HAVING count(*) > 5
) b
JOIN categories ca USING (category_code)
JOIN countries co USING (country_code)
ORDER BY n DESC;
真的不需要CTE。
先聚合,后加入。参见:
- Query with LEFT JOIN not returning rows for count of 0
除了更快,这也更安全。虽然 category_code
、country_code
应该定义为 UNIQUE
,但 continent
和 category
可能并非如此。 (您可能需要额外输出代码以消除歧义。)
count(*)
is implemented 单独且稍快 - 等效于 business
定义为 NOT NULL
.
SQL 中的 CTE 和子查询的新功能。
我有 3 个表:
categories (category_code, category)
countries (country_code, country, continent)
businesses (business, year_founded, category_code, country_code)
目标是了解世界上最古老的企业。我使用了 CTE:
WITH bus_cat_cont AS (
SELECT business, year_founded, category, country,
continent
FROM businesses AS b
INNER JOIN categories AS c1
ON b.category_code = c1.category_code
INNER JOIN countries AS c2
ON b.country_code = c2.country_code
)
SELECT continent,
category,
COUNT(business) AS n
FROM bus_cat_cont
WHERE n > 5
GROUP BY continent, category
ORDER BY n DESC;
代码在没有 WHERE n > 5
的情况下也能正常工作。但是添加之后,我得到了错误:
column "n" does not exist
我意识到有一种更简单的方法可以在没有 CTE 的情况下获得我想要的输出。
但我想知道:为什么会出现此错误?
这可行:
WITH bus_cat_cont AS (
SELECT business, year_founded, category, country, continent
FROM businesses AS b
JOIN categories AS c1 ON b.category_code = c1.category_code
JOIN countries AS c2 ON b.country_code = c2.country_code
)
SELECT continent, category, count(business) AS n
FROM bus_cat_cont
-- WHERE n > 5 -- wrong
GROUP BY continent, category
HAVING count(business) > 5 -- right
ORDER BY n DESC;
output 列名称“n”在 WHERE
或 HAVING
子句中(尚)不可见。考虑 SQL 查询中的事件序列:
- Best way to get result count before LIMIT was applied
郑重声明,该结果与您宣布的 “看看世界上最古老的企业” 的目标没有明显联系。 year_founded
未在查询中使用。
您获得了企业中最常见的 continent/category 组合。
除此之外,可能更好:
SELECT co.continent, ca.category, n
FROM (
SELECT category_code, country_code, count(*) AS n
FROM businesses
GROUP BY 1, 2
HAVING count(*) > 5
) b
JOIN categories ca USING (category_code)
JOIN countries co USING (country_code)
ORDER BY n DESC;
真的不需要CTE。
先聚合,后加入。参见:
- Query with LEFT JOIN not returning rows for count of 0
除了更快,这也更安全。虽然 category_code
、country_code
应该定义为 UNIQUE
,但 continent
和 category
可能并非如此。 (您可能需要额外输出代码以消除歧义。)
count(*)
is implemented 单独且稍快 - 等效于 business
定义为 NOT NULL
.