Sql server 按酒店名称和月份列出的总入住人数和平均停留时间

Sql server 按酒店名称和月份列出的总入住人数和平均停留时间,sql-server,Sql Server,我正在尝试编写一个SQL Server脚本,该脚本按酒店名称和月份显示总入住人数和平均十进制停留时间。任何帮助都将不胜感激 以下是我正在寻找的输出类型: HotelName Month TotalArrivals AvgLengthofStay ============================================================== Algonquin Hotel June 300

我正在尝试编写一个SQL Server脚本,该脚本按酒店名称和月份显示总入住人数和平均十进制停留时间。任何帮助都将不胜感激

以下是我正在寻找的输出类型:

HotelName          Month     TotalArrivals     AvgLengthofStay
==============================================================
Algonquin Hotel    June      300               4.25
Algonquin Hotel    July      375               3.65
The Four Seasons   June      485               4.45    
The Four Seasons   July      445               4.10
The Ritz-Carlton   June      ...               ...
以下是一些相关的表格信息:

HOTEL:

HotelID (PK), HotelName, HotelAddress, HotelCity, HotelState, HotelPostalCode

RESERVATION:

ReservationID (PK), GuestID, RoomID (FK), CheckinDate, NumberofNights

ROOM (Only needed for table joins):

RoomID (PK), HotelID (FK)
编辑:


就“月”而言,我严格按照与签入日期相对应的月份,而不是签出日期进行计算。

在select语句中使用聚合函数(SUM、AVG、COUNT等)时,需要确保按任何非聚合列对语句进行分组。选择的每个非聚合列都会将聚合列分解为更多细节

SELECT HotelName,
       SUM(TotalArrivals) AS TotalArrivals,
       AVG(AvgLengthofStay) AS AvgLengthofStay
FROM dbo.Table
GROUP BY HotelName
此声明将为您提供自您的餐桌使用开始以来每个酒店的总入住人数和总平均入住时间

SELECT HotelName,
       Month,
       SUM(TotalArrivals) AS TotalArrivals,
       AVG(AvgLengthofStay) AS AvgLengthofStay
FROM dbo.Table
GROUP BY HotelName, Month
通过添加月份列,可以进一步分解聚合。现在,数据将返回按酒店划分的总入住人数和平均入住时间,并按月细分

CREATE TABLE #Hotels 
( HotelID int, HotelName varchar(10), HotelAddress  varchar(10), HotelCity  varchar(10), HotelState  varchar(10), HotelPostalCode  varchar(10))

CREATE TABLE #Reservation 
(
 ReservationID int, GuestID int, RoomID int, CheckinDate datetime, NumberofNights int
)

CREATE TABLE #Room
(
 RoomID int, HotelID int

)


INSERT INTO #Hotels (HotelID,HotelName) VALUES (1,'A')
INSERT INTO #Hotels (HotelID,HotelName) VALUES (2,'B')


GO


INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (1,1,1,'2016-01-05',5)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (2,2,1,'2016-08-05',3)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (3,3,1,'2016-06-05',2)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (4,1,1,'2016-01-12',1)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (5,2,1,'2016-08-18',8)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (6,3,1,'2016-06-30',7)





INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (1,1,2,'2016-02-01',5)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (2,2,2,'2016-02-06',3)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (3,3,2,'2016-02-09',2)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (4,1,2,'2016-04-03',1)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (5,2,2,'2016-04-07',8)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (6,3,2,'2016-04-05',7)


INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (1,1,3,'2016-07-01',15)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (2,2,3,'2016-11-06',2)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (3,3,3,'2016-11-09',9)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (4,1,3,'2016-12-03',8)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (5,2,3,'2016-06-07',10)
INSERT INTO #Reservation (ReservationID,GuestID,RoomID,CheckinDate,NumberofNights) 
VALUES (6,3,3,'2016-04-05',2)



INSERT INTO #Room VALUES (1,1)
INSERT INTO #Room VALUES (2,1)
INSERT INTO #Room VALUES (3,2)
“魔力”就在这里

你需要做的是使用一个选择,并按HotelID和MONTH分组(re.CheckinDate),这将给你一个月的基本行数(对于每个酒店,你将得到12行)。使用COUNT(*)将获得特定酒店一个月的所有记录,即总入住量,使用平均值(NumberofNights)将获得平均入住天数

此外,我还使用CASt(将NumberofNights作为十进制(22,6))因为如果NumberofNights是一个int(我假设是),平均值也会返回一个int,因此对于3次到达,10晚返回3,而不是3.333333


希望有帮助

请检查以下SQL Select语句

;with cte as (
select 
    h.HotelID,
    h.HotelName,
    r.ReservationID,
    DATENAME(mm,r.CheckinDate) as [month],
    r.NumberofNights * 1.0 as NumberofNights
from hotel h
inner join ROOM o on o.HotelID = h.HotelID
left join RESERVATION r on r.RoomID = o.RoomID and r.CheckinDate between '20160101' and '20161231'
)
select distinct
    HotelName,
    [month],
    COUNT(ReservationID) over (partition by HotelID, [month]) TotalArrivals,
    cast ( AVG(NumberofNights) over (partition by HotelID, [month]) as decimal(10,2))  AvgLengthofStay
from cte
我假设您作为T-SQL开发人员熟悉

事实上,上面的Select语句很重要,如SUM()、COUNT()、AVG()等

我必须将停留天数乘以1.0才能得到十进制的平均值。 在最后一步中,我将小数转换为整数部分后的2个点


我希望它能帮助您找到解决方案,

研究如何使用
groupby
和聚合函数(如
COUNT
AVG
).如果
CheckinDate
为2016-05-31,而
NumberofNights
为2,该怎么办?您无法准确预测它,因为签入日期可能在月底,并且夜数可能足以进入下个月。那你会怎么做?对不起,说得好!就“月份”而言,我严格按照与入住日期相对应的月份,而不是退房日期。给我们一些数据,以供测试。这会有很大帮助的。我自己没有时间纠正它。干得好,伙计谢谢,CiucaS!这一个似乎真的很接近!唯一不能正常工作的是“TotalArrivals”。COUNT(*)没有给出正确的总数。我基本上是按酒店名称和月份查找预订总数。我尝试了COUNT(re.ReservationID),但这似乎也不起作用。有什么想法吗?@amaidie90发布一些示例数据,以便我可以使用。因为它的理论,这应该工作。
;with cte as (
select 
    h.HotelID,
    h.HotelName,
    r.ReservationID,
    DATENAME(mm,r.CheckinDate) as [month],
    r.NumberofNights * 1.0 as NumberofNights
from hotel h
inner join ROOM o on o.HotelID = h.HotelID
left join RESERVATION r on r.RoomID = o.RoomID and r.CheckinDate between '20160101' and '20161231'
)
select distinct
    HotelName,
    [month],
    COUNT(ReservationID) over (partition by HotelID, [month]) TotalArrivals,
    cast ( AVG(NumberofNights) over (partition by HotelID, [month]) as decimal(10,2))  AvgLengthofStay
from cte