Sql 如何在此查询中选择最大值?考试帮助

Sql 如何在此查询中选择最大值?考试帮助,sql,aggregate-functions,greatest-n-per-group,Sql,Aggregate Functions,Greatest N Per Group,所以,我正在为周四的SQL期末考试做很多练习,我遇到了另一个疑问 练习中的桌子应该来自酒店DB。涉及到三个表: STAY ROOM ROOM_TYPE =========== ============ ============ PK ID_STAY PK ID_ROOM PK ID_ROOM_TYPE DAYS_QUANT

所以,我正在为周四的SQL期末考试做很多练习,我遇到了另一个疑问

练习中的桌子应该来自酒店DB。涉及到三个表:

    STAY               ROOM                  ROOM_TYPE
    ===========        ============          ============
PK  ID_STAY        PK  ID_ROOM           PK  ID_ROOM_TYPE
    DAYS_QUANT         ID_ROOM_TYPE  FK      DESCRIPTION
    DATE               PRICE
    ID_ROOM  FK
他们要求我做的查询是“按房间类型(您必须显示ID房间类型和描述)显示2011年最高天数(总计)的房间的所有数据”

这就是我解决问题的方法,我不知道是否可以:

  SELECT RT.ID_ROOM_TYPE, RT.DESCRIPTON, R.*, SUM(S.DAYS_QUANT)
    FROM STAY S, ROOM R, ROOM_TYPE RT
   WHERE YEAR(S.DATE) = '2011'
GROUP BY RT.ID_ROOM_TYPE, RT.DESCRIPTON, R.*
ORDER BY SUM(S.DAYS_QUANT) DESC
   LIMIT 1
所以,我不确定的第一件事是R.*I包括在内。我能把它放在一个精选的盒子里吗?它是否也可以像那样包含在一个组中

另一件事我不确定是否允许我在考试中使用LIMIT或SELECT TOP 1语句。有人能想出一种不用这些工具就能解决这个问题的方法吗?比如MAX()语句之类的?

这个怎么样

select r.*, t.*
  from room r
  join room_type t on t.id_room_type = r.id_room_type
 where r.id in
       (select
               (select r.id_room
                  from room r
                  join stay on stay.id_room = r.id_room
                 where year(s.date) = '2011'
                   and r.id_room_type = t.id_room_type
                 group by r.id_room
                 order by sum(s.days_quant) desc
                 limit 1) room_id
          from room_type t)
select room.id_room, room_type.description, room.price
from room inner join room_type 
on room.id_room.type = room_type.id_room_type
where room.room_id = (select room_id from stay
where year (date) = 2011
group by id_room
order by sum (days_quant) desc);
不幸的是,这个查询(现在的情况)没有显示最受欢迎的房间租了多少天。但是没有“限制1”

这个怎么样

select room.id_room, room_type.description, room.price
from room inner join room_type 
on room.id_room.type = room_type.id_room_type
where room.room_id = (select room_id from stay
where year (date) = 2011
group by id_room
order by sum (days_quant) desc);

不幸的是,这个查询(现在的情况)没有显示最受欢迎的房间租了多少天。但是没有“限制1”

总是可以避免限制1或选择顶部。一种方法是将顶行表示为没有更高行的行。“不存在的地方”表达了“不存在的地方”的思想

考虑这一点的一种方法是:选择那些没有相同类型且总天数更大的房间(以及它们的总天数和类型信息)。这就给了你这个疑问(没有仔细校对):

如果不能使用CTEs(WITH子句),可以使用子查询重写它,但这样做很尴尬

排序函数作为SQL标准的一部分已经有相当一段时间了。如果您可以使用它们,这也可能起作用:

with StayTotals as (
  select
    STAY.ID_ROOM, 
    ROOM_TYPE.ID_ROOM_TYPE,
    ROOM_TYPE.DESCRIPTION,
    SUM(STAY.DAYS_QUANT) AS TotalDays2011
  from STAY join ROOM on STAY.ID_ROOM = ROOM.ID_ROOM
            join ROOM_TYPE on ROOM.ID_ROOM_TYPE = ROOM_TYPE.ID_ROOM_TYPE
  where YEAR(STAY.DATE) = 2011
  group by STAY.ID_ROOM, ROOM_TYPE.ID_ROOM_TYPE, ROOM_TYPE.DESCRIPTION
), StayTotalsRankedByType as (
  select
    ID_ROOM, 
    ID_ROOM_TYPE,
    DESCRIPTION,
    TotalDays2011,
    RANK() OVER (
      PARTITION BY ID_ROOM_TYPE
      ORDER BY TotalDays2011 DESC
    ) as RankInRoomType
  from StayTotals
)
  select
    ID_ROOM, 
    ID_ROOM_TYPE,
    DESCRIPTION,
    TotalDays2011
  from StayTotalsRankedByType
  where RankInRoomType = 1;

最后,另一种引入其他列来描述分组的MAX结果的方法是使用“carryalong”排序,这是在排名函数可用之前的一种简便方法。Adam Machanic给出了一个例子,Usenet中有一些关于这个主题的有用线索,例如。

总是可以避免限制1或选择顶部。一种方法是将顶行表示为没有更高行的行。“不存在的地方”表达了“不存在的地方”的思想

考虑这一点的一种方法是:选择那些没有相同类型且总天数更大的房间(以及它们的总天数和类型信息)。这就给了你这个疑问(没有仔细校对):

如果不能使用CTEs(WITH子句),可以使用子查询重写它,但这样做很尴尬

排序函数作为SQL标准的一部分已经有相当一段时间了。如果您可以使用它们,这也可能起作用:

with StayTotals as (
  select
    STAY.ID_ROOM, 
    ROOM_TYPE.ID_ROOM_TYPE,
    ROOM_TYPE.DESCRIPTION,
    SUM(STAY.DAYS_QUANT) AS TotalDays2011
  from STAY join ROOM on STAY.ID_ROOM = ROOM.ID_ROOM
            join ROOM_TYPE on ROOM.ID_ROOM_TYPE = ROOM_TYPE.ID_ROOM_TYPE
  where YEAR(STAY.DATE) = 2011
  group by STAY.ID_ROOM, ROOM_TYPE.ID_ROOM_TYPE, ROOM_TYPE.DESCRIPTION
), StayTotalsRankedByType as (
  select
    ID_ROOM, 
    ID_ROOM_TYPE,
    DESCRIPTION,
    TotalDays2011,
    RANK() OVER (
      PARTITION BY ID_ROOM_TYPE
      ORDER BY TotalDays2011 DESC
    ) as RankInRoomType
  from StayTotals
)
  select
    ID_ROOM, 
    ID_ROOM_TYPE,
    DESCRIPTION,
    TotalDays2011
  from StayTotalsRankedByType
  where RankInRoomType = 1;

最后,另一种引入其他列来描述分组的MAX结果的方法是使用“carryalong”排序,这是在排名函数可用之前的一种简便方法。Adam Machanic给出了一个例子,Usenet提供了一些关于这个主题的有用线索,例如。

我认为你不允许使用CTEs,所以我扩展了Steve Kass答案的最后一部分。通过将某个房间的总占用天数与任何相同类型房间的最大总占用天数进行比较,您可能会在没有TOP或Limit子句的情况下获得所需的结果。要做到这一点,您首先要按房间对天数求和,然后使用相同的派生表,得到每个房间类型的最大天数。按房间类型和天数将两者结合起来,可以隔离使用最多的房间。然后加入起始表以显示所有数据。与TOP或Limit不同,在平局时,这将生成更多记录

注意,这是未经测试的。我相信它会起作用,但可能会有打字错误

select r.*, rt.*, roomDays.TotalDays
from Room r inner join Room_type rt
   on r.id_room_type = rt.id_room_type
   inner join 
      (select id_room, id_room_type, sum(days_quant) TotalDays
      from Stay
         inner join Room
           on Stay.id_room = Room.id_room
      where year(Date) = 2011
      group by id_room, id_room_type) roomDays
   on r.id_room = roomDays.id_room
   inner join 
      (select id_room_type, max(TotalDays) TotalDays
      from 
         (select id_room, id_room_type, sum(days_quant) TotalDays
          from Stay
             inner join Room
               on Stay.id_room = Room.id_room
          where year(Date) = 2011
          group by id_room, id_room_type) roomDaysHelper
      group by id_room_type) roomTypeDays
   on r.id_room_type = roomTypeDays.id_room_type
   and roomDays.TotalDays = roomTypeDays.TotalDays

我相信你不允许使用CTEs,所以我扩展了Steve Kass答案的最后一部分。通过将某个房间的总占用天数与任何相同类型房间的最大总占用天数进行比较,您可能会在没有TOP或Limit子句的情况下获得所需的结果。要做到这一点,您首先要按房间对天数求和,然后使用相同的派生表,得到每个房间类型的最大天数。按房间类型和天数将两者结合起来,可以隔离使用最多的房间。然后加入起始表以显示所有数据。与TOP或Limit不同,在平局时,这将生成更多记录

注意,这是未经测试的。我相信它会起作用,但可能会有打字错误

select r.*, rt.*, roomDays.TotalDays
from Room r inner join Room_type rt
   on r.id_room_type = rt.id_room_type
   inner join 
      (select id_room, id_room_type, sum(days_quant) TotalDays
      from Stay
         inner join Room
           on Stay.id_room = Room.id_room
      where year(Date) = 2011
      group by id_room, id_room_type) roomDays
   on r.id_room = roomDays.id_room
   inner join 
      (select id_room_type, max(TotalDays) TotalDays
      from 
         (select id_room, id_room_type, sum(days_quant) TotalDays
          from Stay
             inner join Room
               on Stay.id_room = Room.id_room
          where year(Date) = 2011
          group by id_room, id_room_type) roomDaysHelper
      group by id_room_type) roomTypeDays
   on r.id_room_type = roomTypeDays.id_room_type
   and roomDays.TotalDays = roomTypeDays.TotalDays

谢谢大家!!有了你给我的所有想法,我想到了这个,如果你认为可以请告诉我

SELECT R.ID_ROOM, R.ID_ROOM_TYPE, T.DESCRIPTION, SUM(S.DAYS_CUANT)
FROM ROOM R, ROOM_TYPE T, STAY S
(SELECT ID_STAY, SUM(S.DAYS_QUANT) TOTALDAYS
 FROM STAY S
 WHERE YEAR(S.DATE) = 2011
 GROUP BY S.ID_STAY) STAYHELPER
WHERE YEAR(S.DATE) = 2011 
GROUP BY R.ID_ROOM, R.ID_ROOM_TYPE, T.DESCRIPTION
HAVING SUM(S.DAYS_QUANT) >= ALL STAYHELPER.TOTALDAYS

谢谢大家!!有了你给我的所有想法,我想到了这个,如果你认为可以请告诉我

SELECT R.ID_ROOM, R.ID_ROOM_TYPE, T.DESCRIPTION, SUM(S.DAYS_CUANT)
FROM ROOM R, ROOM_TYPE T, STAY S
(SELECT ID_STAY, SUM(S.DAYS_QUANT) TOTALDAYS
 FROM STAY S
 WHERE YEAR(S.DATE) = 2011
 GROUP BY S.ID_STAY) STAYHELPER
WHERE YEAR(S.DATE) = 2011 
GROUP BY R.ID_ROOM, R.ID_ROOM_TYPE, T.DESCRIPTION
HAVING SUM(S.DAYS_QUANT) >= ALL STAYHELPER.TOTALDAYS

LIMIT
不是ANSI,仅在MySQL、PostgreSQL和SQLite上受支持
FETCH FIRST#ROWS
是ANSI,但只是最近…@OMG Ponies所以…可能教授不会让我们在考试中这样做,因为它最近才被添加到ANSI中…我想我最好找到另一种方法来执行此查询
LIMIT
不是ANSI,并且只在MySQL、PostgreSQL和SQLite上受支持
FETCH FIRST#ROWS
是ANSI,但只是最近…@OMG Ponies所以…可能教授不会让我们在考试中这样做,因为它最近才被添加到ANSI中…我想我最好找到另一种方法来做这个查询,一种很好的方法来做,但这种方法也使用“限制1”。您认为有一种简单的方法可以做到这一点,而不需要“限制”或“选择顶部”语句吗?这也是一种很好的方法,但这种方法也使用了“限制1”。你认为没有“限制”或“选择顶部”的声明,有一种简单的方法可以做到这一点吗?我认为这行不通。子查询(从…选择房间id)通常返回多个值。(也没有名为room_id的列)我认为这行不通。子查询(从…选择房间id)通常返回多个值。(也没有名为room_id的列。)