【发布时间】:2017-02-22 13:53:30
【问题描述】:
- 此挑战基于涉及 IP 范围的真实用例。
- 我提供的解决方案基于我之前提出的stack trace 挑战。每个范围开始都被视为 PUSH 操作,每个范围结束 + 1 被视为 POP 操作。
挑战
我们有一个范围数据集,其中每个范围都有一个起点、终点和一个值。
create table ranges
(
range_start int not null
,range_end int not null
,range_val char(1) not null
)
;
一个范围可以包含另一个范围或跟随另一个范围,但不能等于另一个范围或与另一个范围相交。
这些是范围之间的有效关系:
(1) (2) (3) (4)
--------- --------- --------- -------- -----------
--- --- ---
这些关系无效:
(5) (6)
------- --------
------- --------
我们的初始范围,当以图形方式显示时,可能看起来像这样(字母代表 range_val):
AAAAAAAA BBCCCCCCC
DDE F GGGGG
H IIII
J
目标是获取初始范围集并根据以下规则创建一个新集:
包含范围将覆盖包含范围的相应子范围。
请求的结果,当以图形方式呈现时,可能看起来像这样
ADDHAAAF BIIJIGCCC
要求
- 解决方案应该是单个 SQL 查询(子查询很好)。
- 使用 T-SQL、PL/SQL 等不允许。
- UDF(用户定义函数)的使用不允许。
数据样本
AAAAAAAAAAAAAAAAAAAAAAAAAAAA BBBB CCCCCCCCCCCCCCCCCCCCCCCCC
DDDE FFFFFFFF GGGGGGGGG HHHHHHHH IIIIIII
JJ KKKLLL MM NN OOOOO
P QQ
insert into ranges (range_start,range_end,range_val) values (1 ,28 ,'A');
insert into ranges (range_start,range_end,range_val) values (31 ,34 ,'B');
insert into ranges (range_start,range_end,range_val) values (39 ,63 ,'C');
insert into ranges (range_start,range_end,range_val) values (1 ,3 ,'D');
insert into ranges (range_start,range_end,range_val) values (4 ,4 ,'E');
insert into ranges (range_start,range_end,range_val) values (7 ,14 ,'F');
insert into ranges (range_start,range_end,range_val) values (19 ,27 ,'G');
insert into ranges (range_start,range_end,range_val) values (43 ,50 ,'H');
insert into ranges (range_start,range_end,range_val) values (55 ,61 ,'I');
insert into ranges (range_start,range_end,range_val) values (1 ,2 ,'J');
insert into ranges (range_start,range_end,range_val) values (9 ,11 ,'K');
insert into ranges (range_start,range_end,range_val) values (12 ,14 ,'L');
insert into ranges (range_start,range_end,range_val) values (22 ,23 ,'M');
insert into ranges (range_start,range_end,range_val) values (25 ,26 ,'N');
insert into ranges (range_start,range_end,range_val) values (57 ,61 ,'O');
insert into ranges (range_start,range_end,range_val) values (13 ,13 ,'P');
insert into ranges (range_start,range_end,range_val) values (60 ,61 ,'Q');
要求的结果
(Null 在此处显示为空格)
JJDEAAFFKKKLPLAAAAGGGMMGNNGA BBBB CCCCHHHHHHHHCCCCIIOOOQQCC
range_start range_end range_val
----------- --------- ---------
1 2 J
3 3 D
4 4 E
5 6 A
7 8 F
9 11 K
12 12 L
13 13 P
14 14 L
15 18 A
19 21 G
22 23 M
24 24 G
25 26 N
27 27 G
28 28 A
29 30
31 34 B
35 38
39 42 C
43 50 H
51 54 C
55 56 I
57 59 O
60 61 Q
62 63 C
可选添加最后一行:
64
【问题讨论】:
-
请编辑您的问题以仅包含相关标签。
-
@ZoharPeled,标签已删除。
-
除 SQL 之外的任何建议标签?
-
是的,无论您实际使用的是什么 rdbms。
-
我已标记的所有内容。 Teradata、Oracle、SQL Server、PostgresSQL 和 Hive。我们在另一篇文章中进行了类似的讨论,如您所见,除了供应商特定的解决方案外,我已经为所有这些数据库提交了一个通用解决方案。 stackoverflow.com/a/39941615/6336479
标签: sql sql-server oracle hive teradata