根据我的理解,GROUP BY将返回2个元组。
MODEL ITEM_TYPE PRICE
---------------------------- ------------------------------------- ----------
010-99-0101 BACKPACK 5329.1
626-21-1500 BACKPACK 1485.86
平均价格的价值是,
AVG(PRICE)
----------
4858.014444
因此,以下查询应筛选出较小的价格值。
SELECT item_type, MODEL, items.price
FROM ITEMS
WHERE MANUFACTURER_NAME = 'UWZ'
AND ITEM_TYPE = 'BACKPACK'
GROUP BY item_type, items.price, MODEL
HAVING ITEMS.PRICE > AVG(ITEMS.PRICE);
所以,输出应该是:
MODEL ITEM_TYPE PRICE
---------------------------- ------------------------------------- ----------
010-99-0101 BACKPACK 5329.1
但实际上,以下是输出:
输出
no rows selected
答案 0 :(得分:5)
认为这个查询完成了你想要的工作:
SELECT MODEL, ITEM_TYPE, PRICE
FROM ITEMS
WHERE MANUFACTURER_NAME = 'UWZ'
AND ITEM_TYPE = 'BACKPACK'
AND PRICE >
(SELECT AVG(ITEMS.PRICE)
FROM ITEMS
WHERE MANUFACTURER_NAME = 'UWZ'
AND ITEM_TYPE = 'BACKPACK');
<强> SQL Fiddle demo 强>
<强>解释强>
您尝试使用GROUP BY
效果不佳。您可以在发布的查询的this modification中看到此消息 - 已删除HAVING
子句并添加了一列来计算每个组中的项目数:每个仅1 >。 GROUP BY
可以用来计算平均值,但是一旦计算了这个平均值,它就是需要挑选出的各个行 - 当它们被聚合到一个组中时无法完成。因此需要两个单独的操作 - 聚合函数来查找平均值,选择来挑选感兴趣的行。
答案 1 :(得分:2)
当前查询中的HAVING子句是获取行,其中该行的价格仅大于该行的平均价格 。
单个数字的平均值等于数字,因此不返回任何行。
您可以通过将HAVING子句更改为ITEMS.PRICE = AVG(ITEMS.PRICE)来测试此项 - 这将返回所有行。
窗口函数对于这种查询很方便。下面的OVER子句指定AVG_PRICE将平均值应用于给定制造商和项目类型的所有行。
select *
from (
select MODEL,
ITEM_TYPE,
PRICE,
avg(PRICE) over(
partition by MANUFACTURER_NAME, ITEM_TYPE
) as AVG_PRICE
from ITEMS
) as ITEMS_WITH_AVG
where PRICE > AVG_PRICE
您可能还想查阅window/analytic functions in Oracle上的文档。
答案 2 :(得分:1)
假设您不想总是只返回&#39; UWZ&#39;的记录。和&#39; BACKPACK&#39;您可以使用下面的查询,它使用子查询(派生表)。它建立在与史蒂夫·钱伯斯的回答相同的原则基础上,所以我不会重复这个解释。
您可以取消注释WHERE子句中的其他条件以返回原始答案。
SELECT MODEL
, ITEMS1.ITEM_TYPE
, ITEMS1.MANUFACTURER_NAME
, PRICE
FROM ITEMS ITEMS1
INNER JOIN (SELECT ITEM_TYPE
, MANUFACTURER_NAME
, AVG(PRICE) AVG_PRICE
FROM ITEMS
GROUP BY ITEM_TYPE
, MANUFACTURER_NAME) ITEMS2
ON ITEMS1.ITEM_TYPE = ITEMS2.ITEM_TYPE
AND ITEMS1.MANUFACTURER_NAME = ITEMS2.MANUFACTURER_NAME
WHERE PRICE > AVG_PRICE
--AND ITEMS1.MANUFACTURER_NAME = 'UWZ'
--AND ITEMS1.ITEM_TYPE = 'BACKPACK'
答案 3 :(得分:0)
您需要将查询更改为以下内容:
SELECT Distinct MODEL, item_type, price
FROM ITEMS
WHERE MANUFACTURER_NAME = 'UWZ'
AND ITEM_TYPE = 'BACKPACK'
And Price > (Select Avg(Price) From Items)
如果您出于某种原因想保留GROUP BY
,可以改为:
SELECT MODEL, item_type, items.price
FROM ITEMS
WHERE MANUFACTURER_NAME = 'UWZ'
AND ITEM_TYPE = 'BACKPACK'
GROUP BY item_type, items.price, MODEL
Having Price > (Select Avg(Price) From Items)
您的查询未返回任何结果的原因是AVG(ITEMS.PRICE)
超过了GROUP BY
,因此会返回5329.1
。并且5329.1
既不大于也不小于(编辑前的原始查询)5329.1
。因此,你没有得到任何结果。
从我收集的内容来看,您正在寻找那些大于表格中所有项目的AVG
的内容,这可以通过上述查询来实现。
您可以通过以下方式自行检查:
SELECT item_type, MODEL, items.price, AVG(ITEMS.PRICE) As average
FROM ITEMS
WHERE MANUFACTURER_NAME = 'UWZ'
AND ITEM_TYPE = 'BACKPACK'
GROUP BY item_type, items.price, MODEL
结果:
item_type MODEL price average
------------------------------------------------
BACKPACK 010-99-0101 5329.1 5329.1
答案 4 :(得分:0)
您按item_type
,price
和model
进行分组。这意味着您可以按item_type
,price
和model
获得一个结果行。例如,item_type = 'BACKPACK'
和price = 3915.73
以及model = '172-50-2742'
的一行。表格中是否有同一item_type
,price
和model
的两条记录?因为这是将它们分组的唯一原因。
对于每个此类行,您希望显示item_type
,model
和price
,这只是您要分组的三列。没有其他信息,例如与item_type
,price
和model
匹配的行数,或此合并的库存数量。你会得到与
select distinct item_type, model, price
然后到你的子句:price
应大于avg(price)
组。让我们再次使用price = 3915.73
组。价格为3915.73,所有3915.73价格的平均价格当然也是3915.73。你也可以写having price > price
。当然,价格永远不会超过自身,而且标准永远不会满足。您没有相应的结果行。
您所命名的平均价格4858.014444是表格中所有记录的平均价格。那么你想选择价格高于此的所有UWZ / BACKPACK记录吗?
select *
from items
where manufacturer_name = 'UWZ'
and item_type = 'BACKPACK'
and price > (select avg(all_items.price) from items all_items);
虽然你比较所有产品的平均值,但这似乎很奇怪。与所有BACKPACK进行比较似乎更自然。为此,您必须将此条件添加到子查询中。