计算 SQL 中每个客户的先前交易数(ER 到 DW)

Count number of previous transactions per customer in SQL (ER to DW)

我必须计算客户先前预订的数量与当前预订的数量。请参阅下面的所需输出。

HotelID RoomID BookingID PrevBookingCount  
H6  R8  G3  B1  0  
H6  R2  G5  B2  0  
H6  R7  G1  B3  0  
H10 R4  G7  B4  0  
H10 R9  G2  B5  0  
H13 R1  G11 B6  0  
H13 R8  G1  B7  1  
H13 R5  G5  B8  1  
H13 R3  G1  B9  2  

第三列表示GuestID。这是必须计算以确定以前预订的字段。例如,请参阅预订 B3(第 3 行)具有 GuestID G1。该客户有第一个预订 B1。以前的预订必须为零。预订 B7 再次由客人 G1 进行,但现在该客户有一个先前的预订。同样适用于预订 B9。

table 已创建,PrevBookingCount 设置为 NULL,必须使用更新或更改 table 语句来传递结果。

create table bookings
(HotelID varchar(4),
RoomID varchar(4),
BookingID varchar(4),
PrevBookingCount int)

insert into bookings
values('H6','R8','G3','B1',NULL)
values('H6','R2','G5','B2',NULL)
...
values('H13','R3','G1','B9',NULL)

我接下来的(糟糕的)尝试为每条记录生成了相同的值 (6)。

update bookings
set PrevBookingCount = count(distinct GuestID)

是否有一些迭代方法或子查询可以提供结果?

SQL tables代表无序集合。没有 "previous booking" 这样的东西,除非列提供了该信息。我推测 bookingid 会这样做。

那么,我推荐使用row_number():

select b.*,
       row_number() over (partition by guestid order by bookingid) - 1 as PrevBookingCount
from bookings b;

我认为没有理由将其作为单独的一列保留在 table 中,因为它很容易计算。

但是,如果您真的想这样做,那么标准的 SQL 语法将是:

update bookings
    set PrevBookingCount = (select count(*)
                            from bookings b2
                            where b2.GuestID = b.GuestId and
                                  b2.BookingId < b.BookingId
                           );

这似乎不必要地昂贵,并且会随着下一次数据库更改而过时。