SQL查询:为何无法按会员历史区间表对指定时段租赁值分组求和
问题核心原因
- 未将租赁日期与用户属性的生效区间做绑定匹配,导致单条租赁记录和所有同用户的属性行产生笛卡尔积,所有分组统计到全量时长
- 多维度多次关联用户属性历史表时未绑定租赁日期,进一步放大重复计算问题
- GROUP BY字段设置错误,不需要将r.type、r.hours加入分组,会导致聚合逻辑失效
正确实现逻辑
先以租赁记录为核心,分别关联租赁发生时生效的会员等级、平台、国家属性,再按维度分组统计即可,参考SQL如下:
SELECT p.name AS 客户名称, g.offer AS 会员等级, pl.name AS 使用平台, ctry.name AS 所属国家, SUM(CASE WHEN r.Type = 10 THEN r.hours ELSE 0 END) AS 单日租赁总时长 FROM client p -- 关联租赁记录,先过滤指定时段的租赁 INNER JOIN rent r ON r.owner_id = p.c_id AND r.Date BETWEEN '2021-01-01' AND '2021-06-30' -- 关联租赁发生时生效的会员等级 LEFT JOIN userHistory gh ON gh.user_cid = p.c_id AND gh.type = 'group' AND r.Date >= gh.`from` AND r.Date <= gh.`to` LEFT JOIN `group` g ON g.group_id = gh.item_id -- 关联租赁发生时生效的平台 LEFT JOIN userHistory ph ON ph.user_cid = p.c_id AND ph.type = 'plateform' AND r.Date >= ph.`from` AND r.Date <= ph.`to` LEFT JOIN plateform pl ON pl.plateform_id = ph.item_id -- 关联租赁发生时生效的国家 LEFT JOIN userHistory ch ON ch.user_cid = p.c_id AND ch.type = 'country' AND r.Date >= ch.`from` AND r.Date <= ch.`to` LEFT JOIN country ctry ON ctry.country_id = ch.item_id WHERE p.c_id = 'poa' GROUP BY p.name, g.offer, pl.name, ctry.name
注意事项
- SQL关键字
from、group需要用反引号转义避免语法错误 - 所有属性历史表的关联都要绑定租赁日期
r.Date在属性的生效区间内,避免笛卡尔积 - 如果仅需要按会员等级分组,移除SELECT和GROUP BY里的平台、国家相关字段即可,执行后即可得到free等级时长8、VIP等级时长7.3的预期结果
内容的提问来源于stack exchange,提问作者Louis Chopard
相关产品推荐
相关产品推荐

