如何让我的子查询返回AVG?

时间:2016-10-19 16:56:38

标签: sql oracle

我是subquerys的新手,我想更好地了解它们。我试着说出我的输出是什么(价格高于平均车价的车辆):

Model
-------------
Q60
Q70

但是我目前没有返回任何行,我不确定为什么。我希望这是一个子查询,而不是。但

以下是我的发言:

SELECT t1.MODELNAME AS "Model"
FROM TBLMODEL t1
FULL JOIN TBLVEHICLE t2 ON t1.MODELID = t2.MODELID
WHERE t2.VEHICLEPRICE IN
(
  SELECT AVG(VEHICLEPRICE)    
  FROM TBLVEHICLE    
  GROUP BY VEHICLEPRICE
  HAVING AVG(VEHICLEPRICE) < VEHICLEPRICE  
);

这是与之相关的文件:

DROP TABLE  tblOptionDetail;
DROP TABLE  tblOption;
DROP TABLE  tblVehicle;
DROP TABLE  tblModel;
DROP TABLE  tblBrand;
DROP TABLE  tblManufacture;


CREATE TABLE tblManufacture
(
ManufactureID NUMBER(38) PRIMARY KEY,
ManufactureName CHAR(40)
);

CREATE TABLE tblBrand
(
BrandID NUMBER(38) PRIMARY KEY,
ManufactureID NUMBER(38),
BrandName CHAR(40),
FOREIGN KEY (ManufactureID) REFERENCES tblManufacture(ManufactureID)
);

CREATE TABLE tblModel
(
ModelID NUMBER(38) PRIMARY KEY,
BrandID NUMBER(38),
ModelName CHAR(40),
FOREIGN KEY (BrandID) REFERENCES tblBrand(BrandID)
);

CREATE TABLE tblVehicle
(
VehicleID NUMBER(38) PRIMARY KEY,
ModelID NUMBER(38),
VehicleYear NUMBER(38) CHECK (VehicleYear BETWEEN 1900 and 3000),
VehicleKM NUMBER(38) CHECK (VehicleKM BETWEEN 0 and 100000000),
VehiclePrice NUMBER(38) CONSTRAINT carprice CHECK (VehiclePrice BETWEEN 0 and 1000000),
FOREIGN KEY (ModelID) REFERENCES tblModel(ModelID)
);

CREATE TABLE tblOption
(
OptionID NUMBER(38) PRIMARY KEY,
OptionDesc CHAR(40)
);

CREATE TABLE tblOptionDetail
(
OptionID NUMBER(38),
VehicleID NUMBER(38),
PRIMARY KEY (OptionID, VehicleID),
FOREIGN KEY (OptionID) REFERENCES tblOption(OptionID),
FOREIGN KEY (VehicleID) REFERENCES tblVehicle(VehicleID)
);


-- populate the Manufacture table

INSERT ALL 
INTO tblManufacture (ManufactureID, ManufactureName) VALUES (1,'Chrysler Corp.')
INTO tblManufacture (ManufactureID, ManufactureName) VALUES(2,'General Motors')
INTO tblManufacture (ManufactureID, ManufactureName) VALUES(3,'Ford Motor Company')
INTO tblManufacture (ManufactureID, ManufactureName) VALUES(4,'Toyota')
INTO tblManufacture (ManufactureID, ManufactureName) VALUES (5,'Honda')
INTO tblManufacture (ManufactureID, ManufactureName) VALUES (6,'Nisan')
SELECT * FROM dual;

-- populate the Brand table

INSERT ALL
INTO tblBrand (BrandID, ManufactureID, BrandName) VALUES (1,1, 'Chrysler')
INTO tblBrand (BrandID, ManufactureID, BrandName) VALUES (2,1, 'Dodge')
INTO tblBrand (BrandID, ManufactureID, BrandName) VALUES (3,1, 'Jeep')
INTO tblBrand (BrandID, ManufactureID, BrandName) VALUES (4,2, 'Chevrolet')
INTO tblBrand (BrandID, ManufactureID, BrandName) VALUES (5,2, 'Buick')
INTO tblBrand (BrandID, ManufactureID, BrandName) VALUES (6,2, 'Cadillac')
INTO tblBrand (BrandID, ManufactureID, BrandName) VALUES (7,2, 'GMC')
INTO tblBrand (BrandID, ManufactureID, BrandName) VALUES (8,4, 'Toyota')
INTO tblBrand (BrandID, ManufactureID, BrandName) VALUES (9,6, 'Nissan')
INTO tblBrand (BrandID, ManufactureID, BrandName) VALUES (10,6,'Infiniti')
SELECT * FROM dual;

-- populate the Model table

INSERT ALL
INTO tblModel (ModelID, BrandID, ModelName) VALUES (1,1, '200')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (2,1, '200 Convertible')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (3,1, '300')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (4,1, 'Town'||' & '||'Country')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (5,2, 'Durango')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (6,2, 'Avenger')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (7,2, 'Challenger')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (8,2, 'Charger')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (9,2, 'Caliber')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (10,2, 'Grand Caravan')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (11,2, 'Journey')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (12,4, 'Sonic')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (13,4, 'Cruze')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (14,4, 'Orlando')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (15,4, 'Colorado')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (16,4, 'Malibu')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (17,8, '4Runner')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (18,8, 'Prius')
INTO tblModel (ModelID, BrandID, ModelName) VALUES  (19,8, 'Camry')
INTO tblModel (ModelID, BrandID, ModelName) VALUES  (20,8, 'Corolla')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (21,9,'Rogue SL')
INTO tblModel (ModelID, BrandID, ModelName) VALUES  (22,9, 'Versa Note')
INTO tblModel (ModelID, BrandID, ModelName) VALUES  (23,9, 'Pathfinder')
INTO tblModel (ModelID, BrandID, ModelName) VALUES  (24,9, 'Altima')
INTO tblModel (ModelID, BrandID, ModelName) VALUES (25,10, 'Q70')
INTO tblModel (ModelID, BrandID, ModelName) VALUES  (26,10, 'Q50')
INTO tblModel (ModelID, BrandID, ModelName) VALUES  (27,10, 'Q60')
INTO tblModel (ModelID, BrandID, ModelName) VALUES  (28,10, 'EX37')
SELECT * FROM dual;

-- populate Option table

INSERT ALL 
INTO tblOption (OptionID,OptionDesc) VALUES (1,'Power locks')
INTO tblOption (OptionID,OptionDesc) VALUES (2,'Power windows')
INTO tblOption (OptionID,OptionDesc) VALUES (3,'Air conditioning')
INTO tblOption (OptionID,OptionDesc) VALUES (4,'Heated mirrors')
INTO tblOption (OptionID,OptionDesc) VALUES (5,'Remote keyless entry')
INTO tblOption (OptionID,OptionDesc) VALUES (6,'CD Player')
INTO tblOption (OptionID,OptionDesc) VALUES (7,'GPS')
INTO tblOption (OptionID,OptionDesc) VALUES (8,'In-dash DVD player')
INTO tblOption (OptionID,OptionDesc) VALUES (9,'Overhead DVD player')
INTO tblOption (OptionID,OptionDesc) VALUES (10,'Satellite radio')
INTO tblOption (OptionID,OptionDesc) VALUES (11,'MP3 player')
INTO tblOption (OptionID,OptionDesc) VALUES (12,'Antilock braking system')
INTO tblOption (OptionID,OptionDesc) VALUES (13,'Electronic stability system')
INTO tblOption (OptionID,OptionDesc) VALUES (14,'Traction control')
INTO tblOption (OptionID,OptionDesc) VALUES (15,'Cruise control')
INTO tblOption (OptionID,OptionDesc) VALUES (16,'Intelligent cruise control')
INTO tblOption (OptionID,OptionDesc) VALUES (17,'Parking assist system')
INTO tblOption (OptionID,OptionDesc) VALUES (18,'Xenon headlights')
INTO tblOption (OptionID,OptionDesc) VALUES (19,'Aluminum rims')
INTO tblOption (OptionID,OptionDesc) VALUES (20,'AWD')
INTO tblOption (OptionID,OptionDesc) VALUES (21,'Convertable')
INTO tblOption (OptionID,OptionDesc) VALUES (22,'Heated Seats')
SELECT * FROM dual;

-- populate Vehicle table

INSERT ALL
INTO tblVehicle (VehicleID,ModelID, VehicleYear, VehicleKM, VehiclePrice) VALUES (1,10, 2010, 45000, 18000)
INTO tblVehicle (VehicleID,ModelID, VehicleYear, VehicleKM, VehiclePrice) VALUES (2,10, 2010, 65420, 17500)
INTO tblVehicle (VehicleID,ModelID, VehicleYear, VehicleKM, VehiclePrice) VALUES (3,16, 2004, 143900, 3200)
INTO tblVehicle (VehicleID,ModelID, VehicleYear, VehicleKM, VehiclePrice) VALUES (4,11, 2010, 38900, 14500)
INTO tblVehicle (VehicleID,ModelID, VehicleYear, VehicleKM, VehiclePrice) VALUES (5,27,2014,17250,45999)
INTO tblVehicle (VehicleID,ModelID, VehicleYear, VehicleKM, VehiclePrice) VALUES (6,25,2015,2900,62300)
INTO tblVehicle (VehicleID,ModelID, VehicleYear, VehicleKM, VehiclePrice) VALUES (7,17,2010,87900,19800)
SELECT * FROM dual;

-- populate OptionDetail table

INSERT ALL
INTO tblOptionDetail (OptionID, VehicleID) VALUES (2, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (1, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (3, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (5, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (6, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (7, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (8, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (11, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (12, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (14, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (15, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (19, 2)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (2, 1)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (1, 1)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (3, 1)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (6, 1)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (12, 1)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (14, 1)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (15, 1)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (19, 1)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (2, 3)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (1, 3)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (3, 3)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (6, 3)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (12, 3)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (14, 3)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (15, 3)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (19, 3)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (2, 4)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (1, 4)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (3, 4)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (6, 4)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (11, 4)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (12, 4)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (14, 4)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (15, 4)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (19, 4)
INTO tblOptionDetail (OptionID, VehicleID) VALUES  (4,5)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (8,5)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (1,5)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (2,5)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (5,5)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (21,6)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (22,6)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (3,6)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (1,6)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (2,6)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (1,7)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (4,7)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (5,7)
INTO tblOptionDetail (OptionID, VehicleID) VALUES (2,7)
SELECT * FROM dual;

COMMIT;

2 个答案:

答案 0 :(得分:2)

首先让我们分析你的尝试 - 也许可以从中学到一些东西。 (我提供下面的工作答案,不用担心!)

在子查询中,您将获取tblVehicle表中的所有行。然后按价格对它们进行分组;因此,如果三辆车的价格相同,只需25,000美元,那么它们就属于一组。 (大多数群体可能只有一行,因为不同车辆的价格很少相同。)

然后在每个组中计算组的平均价格,并与同一组中的价格进行比较。这就是HAVING的工作原理:它孤立地对待每个组,就好像这些是唯一正在考虑的行。

因此,在您的情况下,组中的所有行具有相同的价格 - 因此平均值也相同,等于该组中每辆车的价格。所以<比较显然会在每一种情况下失败 - 你将得不到任何行。那就是:即使在SUBQUERY中也没有行。然后你将它用于IN - 但由于子查询没有返回任何行,因此&#34;&#34;子查询中的列表,因此整个查询也不返回任何行。

还有一件事 - 你很幸运,vehicleprice甚至可以在HAVING子句中使用。它可用,因为您按该列分组;其他列(不包括在GROUP BY列表中)在HAVING子句中不可用,您将收到语法错误。

现在找到正确的解决方案:您需要将每辆车的价格与所有车辆的平均价格进行比较。所有车辆的平均值是唯一的&#34;奇怪的&#34;数量,您必须通过遍历整个表来计算。所以它就是你需要在子查询中计算的东西。

喜欢这样:(注意我不喜欢&#34; ......&#34;对于列名称 - 不是一个好习惯)

SELECT t1.MODELNAME AS model
FROM TBLMODEL t1
FULL JOIN TBLVEHICLE t2 ON t1.MODELID = t2.MODELID
WHERE t2.VEHICLEPRICE >
(
  SELECT AVG(VEHICLEPRICE)    
  FROM TBLVEHICLE     
);

请注意,子查询只返回一行,其中包含一列 - 单个值。这被称为&#34;标量&#34;子查询,它返回的值可以被用作好像它是一个独立的&#34;值(而不是子查询的结果)。您可以将其与>条件进行比较,就像您要与简单数字进行比较一样。

答案 1 :(得分:0)

这是你问题的答案:

SELECT m.MODELNAME AS "Model"
FROM TBLMODEL m JOIN
     TBLVEHICLE v
     ON m.MODELID = v.MODELID
WHERE t2.VEHICLEPRICE > (SELECT AVG(VEHICLEPRICE)    
                         FROM TBLVEHICLE  
                        )  ;

从哪里开始查询问题。

  • 不需要FULL JOIN。实际上,WHERE过滤掉了不匹配的行,将full join转换为leftright外部联接。
  • 子查询正在AVG(VEHICLEPRICE)并按VEHICLEPRICE分组。嗯,这很容易计算。如果值完全相同,则值只是VEHICLEPRICE
  • HAVING条款很难遵循。您只保留平均值严格小于外部值的行。
  • 好吧,IN永远不会匹配严格小于它的值。
  • 并且,当您使用表别名时,请将它们作为表的缩写。