SQL查询返回无效0值行问题求助:筛选有效客户统计数据
解决SQL统计过滤问题
表结构
我有以下三张表:
___Kardex
| KDX_Id | KDX_VIP | KDX_Regular |
|---|---|---|
| 1 | No | No |
| 2 | No | No |
___BillableDatas
| BIL_Id | BIL_BookingId |
|---|---|
| 1 | 99 |
| 2 | 99 |
| 3 | 100 |
___Bookings
| BOO_Id | BOO_ClientId |
|---|---|
| 99 | 1 |
| 100 | 2 |
需求
我需要遍历___Kardex表,为每个客户统计:
- 客户的预订数量(数据来自
___Bookings表) - 客户的入住晚数(数据来自
___BillableDatas表)
同时,只希望返回nb_bookings或nb_nights >= 1的行。
我尝试的SQL语句
SELECT KDX_Id, ( SELECT COUNT(BOO_Id) FROM ___Bookings WHERE KDX_Id = ___Bookings.BOO_ClientId ) AS nb_bookings, ( SELECT COUNT(BIL_Id) FROM ___Bookings, ___BillableDatas WHERE ___Bookings.BOO_Id = ___BillableDatas.BIL_BookingId AND KDX_Id = ___Bookings.BOO_ClientId ) AS nb_nights FROM ___Kardex
问题在于:该查询返回了___Kardex表中的所有行,但我只需要保留有预订或入住记录的客户。
解决方案
你可以通过两种方式实现需求:
方法1:在原查询基础上添加WHERE子句
直接过滤掉两个统计值都为0的行,同时把隐式关联改成更规范的显式JOIN:
SELECT KDX_Id, (SELECT COUNT(BOO_Id) FROM ___Bookings WHERE KDX_Id = ___Bookings.BOO_ClientId) AS nb_bookings, (SELECT COUNT(BIL_Id) FROM ___Bookings JOIN ___BillableDatas ON ___Bookings.BOO_Id = ___BillableDatas.BIL_BookingId WHERE KDX_Id = ___Bookings.BOO_ClientId) AS nb_nights FROM ___Kardex WHERE nb_bookings >= 1 OR nb_nights >= 1;
方法2:使用JOIN+聚合函数(更高效)
通过关联表后聚合统计,天然过滤无匹配记录的客户,同时用DISTINCT避免重复统计预订数:
SELECT k.KDX_Id, COUNT(DISTINCT b.BOO_Id) AS nb_bookings, COUNT(bd.BIL_Id) AS nb_nights FROM ___Kardex k LEFT JOIN ___Bookings b ON k.KDX_Id = b.BOO_ClientId LEFT JOIN ___BillableDatas bd ON b.BOO_Id = bd.BIL_BookingId GROUP BY k.KDX_Id HAVING COUNT(DISTINCT b.BOO_Id) >= 1 OR COUNT(bd.BIL_Id) >= 1;
预期结果
| KDX_Id | nb_bookings | nb_nights |
|---|---|---|
| 1 | 1 | 2 |
| 2 | 1 | 1 |
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

