使用子查询将价格列与类别的平均价格进行比较

Posted

技术标签:

【中文标题】使用子查询将价格列与类别的平均价格进行比较【英文标题】:Using subquery to compare the price column with the average price of the categories 【发布时间】:2020-06-13 01:45:08 【问题描述】:

我正在尝试使用两个表(类别和产品)来生成一个包含 category_name 和 product_price 的表。 product_price 变量应该是大于特定类别中产品平均价格的标价。我必须使用子查询来生成此表。

子查询写在 WHERE 子句中,它将价格与每个类别的平均价格进行比较。主 Select 语句和子查询似乎都可以完美地分开工作。但是,当我尝试完全运行它们时,该表会生成所有价格,而不仅仅是高于每个类别平均价格的价格。此外,当我使用 ALL 命令而不是 Any 命令时,它只为一个类别返回 2 行。它不会返回我期望的其他类别的其他 2 行。我在这里有什么遗漏的吗?

【问题讨论】:

你应该摆脱ANY关键字,这就是我的想法。 @Josh 你为什么从你的问题中删除代码?如果它与您的问题无关,请编辑问题并解释。 【参考方案1】:

我认为你想要:

SELECT p.product_name, c.category_name, p.list_price
FROM products p 
INNER JOIN categories c ON p.category_id = c.category_id
WHERE p.list_price > (
    SELECT AVG(p1.list_price) FROM products p1 WHERE on p1.category_id = p.category_id     
) 

相关子查询为您提供同一类别中所有产品的平均价格。这会返回一个 标量 值,因此不需要基于集合的运算符,例如 ALLANY

另外请注意,您的原始查询在 then 子查询和外部查询之间有冲突的表别名(pc 在两种情况下都使用),这导致子查询中的别名确实与哪个表相关到。

最后:如果你运行的是 mysql 8.0(或支持窗口函数的 SQLite 版本),你可以得到与窗口平均值相同的结果:

SELECT product_name, category_name, list_price
FROM (
    SELECT 
        p.product_name, 
        c.category_name, 
        p.list_price, 
        AVG(list_price) OVER(PARTITION BY c.category_id) avg_list_price
    FROM products p 
    INNER JOIN categories c ON p.category_id = c.category_id
) t
WHERE list_price > avg_list_price

【讨论】:

【参考方案2】:

您可以使用相关子查询:

WHERE p.list_price > (SELECT AVG(p2.list_price)
                      FROM products p2
                      WHERE p2.category_id = p.category_id
                     ) 

【讨论】:

以上是关于使用子查询将价格列与类别的平均价格进行比较的主要内容,如果未能解决你的问题,请参考以下文章

MTSQL的子查询

MTSQL的子查询

仅显示子查询中的 1 列:列出平均价格 >= 3 且至少有 2 个不同产品的麸皮名称

查询价格大于或等于"超级本"价格的商品,并且按价格降序排列

查询帮助确定产品的平均价格 < 3

SQL基础教程(第2版)第5章 复杂查询:5-3 关联子查询