SQL动态分配行号:含Meal的同一HOTEL行号统一,否则累加
动态分配行号的SQL解决方案
根据你的需求,我们可以通过两步标记+累积计数的方式实现符合规则的行号分配,核心是先区分哪些酒店包含Meal类型,再针对两类酒店分别计算行号:
实现思路
- 标记酒店是否含Meal类型:用窗口函数给每条记录打上标记,标记其所属酒店是否存在TYPE包含'Meal'的记录。
- 动态计算行号:基于标记结果,对含Meal的酒店,同一酒店的所有记录共享同一个行号;对不含Meal的酒店,每条记录依次累加行号。
示例SQL代码
假设你的表名为hotel_records,包含字段HOTEL、TYPE,以及用于确定记录顺序的字段(比如id或create_time,这里用id示例):
WITH hotel_meal_status AS ( SELECT *, -- 标记当前酒店是否存在含Meal的TYPE MAX(CASE WHEN TYPE LIKE '%Meal%' THEN 1 ELSE 0 END) OVER (PARTITION BY HOTEL) AS has_meal FROM hotel_records ), dynamic_row_calculation AS ( SELECT HOTEL, TYPE, -- 累积计算行号:含Meal的酒店仅第一条记录使计数器+1,无Meal的每条记录+1 SUM( CASE WHEN has_meal = 1 THEN CASE WHEN ROW_NUMBER() OVER (PARTITION BY HOTEL ORDER BY id) = 1 THEN 1 ELSE 0 END ELSE 1 END ) OVER (ORDER BY id) AS dynamic_row_num FROM hotel_meal_status ) SELECT HOTEL, TYPE, dynamic_row_num FROM dynamic_row_calculation ORDER BY id;
代码说明
- 第一个CTE
hotel_meal_status:通过MAX() OVER (PARTITION BY HOTEL),给同一酒店的所有记录统一标记has_meal(1表示该酒店有Meal类型,0表示没有)。 - 第二个CTE
dynamic_row_calculation:用SUM() OVER (ORDER BY id)实现累积计数:- 当
has_meal=1时,仅该酒店的第一条记录(通过ROW_NUMBER() OVER (PARTITION BY HOTEL ORDER BY id)判断)会让计数器加1,后续同酒店记录加0,确保整个酒店的行号一致。 - 当
has_meal=0时,每条记录都让计数器加1,实现行号依次递增。
- 当
如果你的记录顺序不是基于id,只需将代码中的ORDER BY id替换为实际的排序字段(比如create_time)即可。
内容的提问来源于stack exchange,提问作者Debrup
相关产品推荐
相关产品推荐

