范围的样本数据表名为范围如下所示:
+-----------------+-------------------+----------+----------+
| SectionCategory | RangeName | LowerEnd | UpperEnd |
+-----------------+-------------------+----------+----------+
| Sanction | 0-7 days | 0 | 7 |
| Sanction | 8-15 days | 8 | 15 |
| Sanction | More than 15 days | 16 | 99999 |
| Disbursal | 0-7 days | 0 | 7 |
| Disbursal | 8-15 days | 8 | 15 |
| Disbursal | More than 15 days | 16 | 99999 |
+-----------------+-------------------+----------+----------+
来自延迟表的样本数据如下所示:
+-----------+---------------+-----------------+
| Loan No. | SanctionDelay | Disbursal Delay |
+-----------+---------------+-----------------+
| 247 | 8 | 35 |
| 661 | 18 | 37 |
| 1235 | 12 | 6 |
| 1235 | 8 | 15 |
| 1241 | 28 | 9 |
| 1241 | 11 | 9 |
| 1283 | 22 | 20 |
| 1283 | 28 | 41 |
| 1523 | 1 | 27 |
| 1523 | 6 | 28 |
+-----------+---------------+-----------------+
所需的输出如下所示:
+-----------+-------------------+-------+
| Section | Range | Count |
+-----------+-------------------+-------+
| Sanction | 0-7 days | 2 |
| Sanction | 8-15 days | 4 |
| Sanction | More than 15 days | 4 |
| Disbursal | 0-7 days | 1 |
| Disbursal | 8-15 days | 3 |
| Disbursal | More than 15 days | 6 |
+-----------+-------------------+-------+
目前编写了两个单独的查询,UNION用于整理输出。
从可维护性的角度来看,是否可以在单个查询中执行此操作? (对于Ranges表中的制裁,应使用Delays Table中的SanctionDelay列,对于Disbursal,应使用DisbursalDelay列。)需要的是因为贷款生命周期的阶段数预计会增加,并且越来越多的UNIONs需要整理输出。
答案 0 :(得分:3)
可以使用CROSS JOIN
来完成,但不确定效率如何。
示例数据:
declare @Ranges table (SectionCategory varchar(10) not null,RangeName varchar(20) not null,LowerEnd int not null,UpperEnd int not null)
insert into @Ranges (SectionCategory,RangeName,LowerEnd,UpperEnd) values
('Sanction','0-7 days',0,7),
('Sanction','8-15 days',8,15),
('Sanction','More than 15 days',16,99999),
('Disbursal','0-7 days',0,7),
('Disbursal','8-15 days',8,15),
('Disbursal','More than 15 days',16,99999)
declare @Delays table (LoanNo int not null,SanctionDelay int not null,DisbursalDelay int not null)
insert into @Delays (LoanNo,SanctionDelay,DisbursalDelay) values
( 247, 8,35),
( 661,18,37),
(1235,12, 6),
(1235, 8,15),
(1241,28, 9),
(1241,11, 9),
(1283,22,20),
(1283,28,41),
(1523, 1,27),
(1523, 6,28)
查询(必须与样本数据在同一批次中运行):
select
r.SectionCategory,
r.RangeName,
SUM(CASE
WHEN r.SectionCategory='Sanction' and d.SanctionDelay BETWEEN r.LowerEnd and r.UpperEnd then 1
WHEN r.SectionCategory='Disbursal' and d.DisbursalDelay BETWEEN r.LowerEnd and r.UpperEnd then 1
else 0 end) as Cnt
from @Ranges r
cross join
@Delays d
group by
r.SectionCategory,
r.RangeName
order by SectionCategory,RangeName
结果:
SectionCategory RangeName Cnt
--------------- -------------------- -----------
Disbursal 0-7 days 1
Disbursal 8-15 days 3
Disbursal More than 15 days 6
Sanction 0-7 days 2
Sanction 8-15 days 4
Sanction More than 15 days 4
从可维护性的角度来看,在延迟表中添加一个延迟列并指定延迟类型的附加列可能更好。目前,感觉就像某种形式的属性拆分 - 在Ranges表中,类型表示为列值(Sanction
,Disbursal
等),但在延迟表中,这同样“type”在表元数据中以不同的列名称表示。
你说“贷款生命周期的阶段数预计会增加”,我希望这种交叉(代表某些表中的数据属性和其他表中的元数据)将增加痛苦写得体面的查询。
答案 1 :(得分:2)
试试这个
SELECT
SectionCategory
,RangeName
,CASE
WHEN R.SectionCategory='Sanction' THEN
(SELECT COUNT(1) FROM Delays D WHERE D.Sanction_Delay BETWEEN R.LowerEnd AND R.UpperEnd)
WHEN R.SectionCategory='Disbursal' THEN
(SELECT COUNT(1) FROM Delays D WHERE D.[Disbursal Delay] BETWEEN R.LowerEnd AND R.UpperEnd)
END as cnt
FROM Ranges R
这是 SQLFiddle 演示