我在这样的sqlite数据库中有一个视图:
SQL小提琴 (http://www.sqlfiddle.com/#!5/ae95b/1)
这表示盒子和进入每个盒子的物品的列表。项始终按box_start
进行排序,范围box_start
和box_end
永远不会重叠。
如第一行所示,有一个盒子可以存储代码从1(含1)到3(含3)的项目。例如,将在框A中显示的项目为“ a”和“ b”。
框项分组用颜色表示,具有相同颜色的行表示它们是一个组。
也有没有指定框(框标签为空)的项目,例如“ c”,“ f”,“ g”,“ h”。
如果可能的话,我需要编写一个查询来为没有盒子的物品创建临时盒子,并将连续的物品分组到同一盒子中,如下所示:
如图所示,项目“ c”及其对应的框标记为“ 4-4”,以前未分配的项目“ f”,“ g”,“ h”现在被分组在标记为“
对应于'f,g,h的min(box_start
-f(g,h)的max(box_end
)'
我不确定如何在SQLite中执行此操作。我曾考虑过对CTE使用某种递归查询,但不知道如何做。
答案 0 :(得分:0)
工作后,我有以下查询:
select
min(box_start) as box_start,
box_end,
box_label,
is_box,
item_code,
item
from
(
select
box_start,
box_end,
box_label,
is_box,
item_code,
item
from
table1
where
box_label is not null
union all
select
table1.box_start as box_start,
table1.box_end as box_end,
intervals.A || '-' || intervals.B as box_label,
table1.is_box as is_box,
table1.item_code as item_code,
table1.item as item
from
(
select
box_start,
box_end,
box_label,
is_box,
A,
B,
max(max_interval_size) as max_interval_size
from
(
select
box_start,
box_end,
box_label,
is_box,
A,
B,
max(interval_size) as max_interval_size
from
(
select
fixed_table.box_start as box_start,
fixed_table.box_end as box_end,
fixed_table.box_label as box_label,
fixed_table.is_box as is_box,
fixed_table.box_start as A,
windowed_table.box_end as B,
(windowed_table.box_end - fixed_table.box_start) as interval_size
from
table1 fixed_table
join table1 windowed_table on
fixed_table.box_start <= windowed_table.box_end
where
interval_size >= 0
and fixed_table.box_label is null
and windowed_table.box_label is null
and fixed_table.is_box = 'FALSE'
and windowed_table.is_box = 'FALSE'
except
select
without_a_box.*
from
(
select
fixed_table.box_start as box_start,
fixed_table.box_end as box_end,
fixed_table.box_label as box_label,
fixed_table.is_box as is_box,
fixed_table.box_start as A,
windowed_table.box_end as B,
(windowed_table.box_end - fixed_table.box_start) as interval_size
from
table1 fixed_table
join table1 windowed_table on
fixed_table.box_start <= windowed_table.box_end
where
interval_size >= 0
and fixed_table.box_label is null
and windowed_table.box_label is null
and fixed_table.is_box = 'FALSE'
and windowed_table.is_box = 'FALSE'
) as without_a_box
,
(
select distinct
with_box.box_start as start_with_box
from
table1 with_box
where
with_box.is_box = 'FALSE'
and with_box.box_label is not null
) as items_inside_a_box
where
items_inside_a_box.start_with_box > without_a_box.A
and items_inside_a_box.start_with_box < without_a_box.B
) as without_intervals_that_intersect_boxed_items
group by
A
) as final
group by
B
) as intervals
join table1 on
table1.box_start >= intervals.A
and table1.box_end <= intervals.B
and table1.box_label is null
)
group by
box_label,
is_box,
item_code,
item
order by
box_start,
item_code
SQL小提琴:http://www.sqlfiddle.com/#!7/4a643e/142
即使它似乎可以完成工作,但我不确定在所有情况下是否正确,以及它是否不会成为性能瓶颈。
我希望有人有更好的解决方案