GROUP BY 非标准 MySQL 到标准 SQL

GROUP BY non-standard MySQL to standard SQL

我的数据库

Hotel(CodHotel_PK, Name, City)
Customer(CodCustomer_PK, Name, Surname, Address, MobileNumb)
Reservation(CodCustomer_PK_FK, CodHotel_PK_FK, StartDate_PK, NumDays, PricePerDay)

FOR EACH CUSTOMER 我需要找到持续时间少于 9 天的最昂贵的预订,输出必须包含:

[CodCustomer], [total price for reservation], [Hotel name], [reservation StartDate]

这适用于 MySQL 但不适用于标准 SQL

SELECT cu.CodCustomer, MAX(rs.PricePerDay*rs.NumDays), ht.Name, rs.StartDate
FROM Customer cu
JOIN Reservation rs ON cu.CodCustomer = rs.CodCustomer
JOIN Hotel ht ON rs.CodHotel = ht.CodHotel
WHERE rs.NumDays < 9
GROUP BY cu.CodCustomer

预订的主键 table 是复合的,我不能使用单个主键

我如何 运行 标准 SQL?我禁用了非标准扩展 SET SESSION SQL_MODE='ONLY_FULL_GROUP_BY'

I need to find the most expensive booking that last less than nine days.

我认为这里不需要聚合。 order bylimit 似乎足够了:

select 
    cu.codcustomer, 
    rs.priceperday * rs.numdays as total_price, 
    ht.name, 
    rs.startdate
from customer    cu
join reservation rs on cu.codcustomer = rs.codcustomer
join hotel       ht on rs.codhotel    = ht.codhotel
where rs.numdays < 9
order by total_price desc limit 1

编辑

如果每个客户都需要这个,那就有点复杂了,尤其是8.0之前的版本,window的功能是不可用的。基本思想是您需要过滤而不是聚合。一个选项使用相关子查询:

select 
    cu.codcustomer, 
    rs.priceperday * rs.numdays as total_price, 
    ht.name, 
    rs.startdate
from customer    cu
join reservation rs on cu.codcustomer = rs.codcustomer
join hotel       ht on rs.codhotel    = ht.codhotel
where rs.numdays < 9 and rs.priceperday * rs.numdays = (
    select max(rs1.priceperday * rs1.numdays) as total_price
    from reservation rs1
    where rs1.codcustomer = rs.codcustomer and rs1.numdays < 9
)

在 MySQL 8 中,我将为此使用分析函数。在旧版本中,您可以使用聚合子查询:

SELECT cu.CodCustomer, rs.PricePerDay * rs.NumDays, ht.Name, rs.StartDate
FROM Customer cu
JOIN Reservation rs ON cu.CodCustomer = rs.CodCustomer
JOIN Hotel ht ON rs.CodHotel = ht.CodHotel
WHERE rs.NumDays < 9
AND (rs.CodCustomer, rs.priceperday * rs.numdays) IN
(
  SELECT codcustomer, MAX(priceperday * numdays)
  FROM reservation
  WHERE numdays < 9
  GROUP BY codcustomer
);