Sql 为什么在使用MIN函数并选择另一列时,我们需要GROUPBY子句?不';t分钟返回单记录?

Sql 为什么在使用MIN函数并选择另一列时,我们需要GROUPBY子句?不';t分钟返回单记录?,sql,postgresql,Sql,Postgresql,我有两个表车辆和经销商车辆。经销商\ U车辆表中有一个价格列。车辆表中有一列经销商车辆id,该列与经销商车辆表中的经销商车辆id列相关 我只想退回最便宜的汽车 为什么会出现以下查询: select vehicles.make, MIN(dealership_vehicles.price) from vehicles inner join dealership_vehicles on vehicles.dealership_vehicle_id=deale

我有两个表
车辆
经销商车辆
经销商\ U车辆
表中有一个价格列。
车辆
表中有一列
经销商车辆id
,该列与
经销商车辆
表中的
经销商车辆
id列相关

我只想退回最便宜的汽车

为什么会出现以下查询:

select 
    vehicles.make, 
    MIN(dealership_vehicles.price) 
from 
    vehicles inner join dealership_vehicles 
    on vehicles.dealership_vehicle_id=dealership_vehicles.id;
返回错误:

column "vehicles.make" must appear in the GROUP BY clause or be used in an aggregate function
由于MIN函数返回单个值,因此可以构造SQL查询来返回单个值,而无需分组依据。

将术语“分组依据”视为“每辆车”。它的意思是“给我每辆车的最低经销商价格。制造”

因此,您需要将查询更改为:

select 
    vehicles.make, 
    MIN(dealership_vehicles.price) 
from 
    vehicles inner join dealership_vehicles 
    on vehicles.dealership_vehicle_id=dealership_vehicles.id
Group by vehicles.make;

如果您想要最便宜的汽车,则无需汇总:

select v.make, dv.price
from vehicles v inner join
     dealership_vehicles  dv
     on v.dealership_vehicle_id = dv.id
order by dv.price asc
fetch first one row only;
如果您希望在打领带的情况下使用所有行,则这会变得稍微复杂一些:

select v.*
from (select v.make, dv.price, rank() over (order by price asc) as seqnum
      from vehicles v inner join
           dealership_vehicles  dv
           on v.dealership_vehicle_id = dv.id
     ) v
where seqnum = 1

因此,假设加入价格后,我们有下表(即存储在#temp表中):

如果查询它的最低价格,而不指定分组依据,则所有行中只应用一个最小值函数。例如:

select min(Price) from #temp
将返回单个值5000.00

如果你想知道最便宜汽车的品牌,你需要用最便宜的价格过滤你的结果——这是一个两步的过程。首先,您可以使用min找出最便宜的价格,然后在单独的查询中,您可以找出哪些汽车的价格是该价格。一旦你正确地构造了你的查询,你会注意到这揭示了你可能没有的东西——你实际上可以有多个最便宜的品牌

示例表:

#temp Vehicles table v2:
| Make   | Model  |    Price |
|--------|--------|----------|
| Toyota | Yaris  |  5000.00 |
| Toyota | Camry  | 10000.00 |
| Ford   | Focus  |  7500.00 |
| Ford   | Escort |  5000.00 |
查询:

select * from #temp
where Price = (select min(Price) from #temp)
结果:

| Make   | Model  |    Price |
|--------|--------|----------|
| Toyota | Yaris  |  5000.00 |
| Ford   | Escort |  5000.00 |

你说你想知道最便宜的汽车的品牌。最简单的方法是

SELECT DISTINCT v.MAKE
  FROM VEHICLE v
  INNER JOIN DEALERSHIP_VEHICLES dv
    ON v.DEALERSHIP_VEHICLE_ID = dv.ID
  WHERE dv.PRICE = (SELECT MIN(PRICE) FROM DEALERSHIP_VEHICLES);
请注意,由于多辆车可能具有“最便宜”的价格,因此完全有可能从上述查询中获得多个返回

祝你好运

编辑 另一种方法是按最低价格,按品牌,然后按最低价格排序,然后只取第一行。差不多

SELECT *
  FROM (SELECT v.MAKE, MIN(dv.PRICE)
          FROM VEHICLE v
          INNER JOIN DEALERSHIP_VEHICLES dv
            ON v.DEALERSHIP_VEHICLE_ID = dv.ID
          GROUP BY v.MAKE
          ORDER BY MIN(dv.PRICE) ASC)
  WHERE ROWNUM = 1;

这种可能的重复实际上是有道理的。我以为MIN()函数只返回一条记录?我认为这会进入经销商\车辆表,在该列中找到最低价格,并返回具有该最低价格的车辆品牌。上面的查询返回多条记录。@O.MeeKoh:
MIN
返回一个值,但该值将附加到每一行,因此仍然会得到一组行。如果不按其他字段对行进行分组,结果几乎永远不会是您想要的结果。在你的例子中,如果它起作用的话,它会是一堆像
(make,MIN(所有行))
这样的行。这正是我要找的!仅返回最便宜车辆品牌的单个查询。我就是不能把它放到SQL上下文中。
SELECT *
  FROM (SELECT v.MAKE, MIN(dv.PRICE)
          FROM VEHICLE v
          INNER JOIN DEALERSHIP_VEHICLES dv
            ON v.DEALERSHIP_VEHICLE_ID = dv.ID
          GROUP BY v.MAKE
          ORDER BY MIN(dv.PRICE) ASC)
  WHERE ROWNUM = 1;