SQL Oracle:如何对患者传输数据进行排序
SQL Oracle: how to sort patient transfer data
我希望你能帮我写下关于病房病人转移的查询。正如你们大多数人所知,患者可以从一个病房转移到另一个病房,也可以从床转移到同一个病房的另一张床,但对于这个查询,我只想 病房转移并且有每个不同单元中每次接送的首次到达和最后更新,并忽略任何床到床的接送,这里是一个例子:
PATIENT_ID Start_Date END_DATE UNIT_NAME BED_NUMBER
----------------------------------------------------------
1 01/01/2015 01/02/2015 A 1
1 01/02/2015 01/03/2015 A 2
1 01/03/2015 01/03/2015 B 1
1 01/03/2015 01/04/2015 C 5
1 01/04/2015 01/06/2015 C 8
1 01/06/2015 01/07/2015 C 9
1 01/07/2015 01/08/2015 A 1
输出应该是:
PATIENT_ID Start_Date END_DATE UNIT_NAME
------------------------------------------------
1 01/01/2015 01/03/2015 A
1 01/03/2015 01/03/2015 B
1 01/03/2015 01/07/2015 C
1 01/07/2015 01/08/2015 A
请注意,患者转移可以在同一天进行多次。
这是 gaps-and-islands problem. You can use Tabibitosan 的方法。完整参考 link
这个方法的解释。
Oracle 11g R2 架构设置:
create table hospi(
patien_id number,
start_date date,
end_date date,
unit_name varchar2(1),
bed_number number
);
insert into hospi values(1, date'2015-01-01', date'2015-01-02', 'A', 1);
insert into hospi values(1, date'2015-01-02', date'2015-01-03', 'A', 2);
insert into hospi values(1, date'2015-01-03', date'2015-01-03', 'B', 1);
insert into hospi values(1, date'2015-01-03', date'2015-01-04', 'C', 5);
insert into hospi values(1, date'2015-01-04', date'2015-01-06', 'C', 8);
insert into hospi values(1, date'2015-01-06', date'2015-01-07', 'C', 9);
insert into hospi values(1, date'2015-01-07', date'2015-01-08', 'A', 1);
insert into hospi values(2, date'2015-01-07', date'2015-01-08', 'A', 1);
insert into hospi values(2, date'2015-01-08', date'2015-01-08', 'B', 1);
insert into hospi values(2, date'2015-01-08', date'2015-01-09', 'B', 1);
查询:
select
patien_id,
min(start_date) start_date,
max(end_date) end_date,
unit_name
from (
select
patien_id,
start_date,
end_date,
unit_name,
row_number() over (partition by patien_id order by start_date, end_date) -
row_number() over (partition by patien_id, unit_name order by start_date, end_date) grp
from hospi
)
group by
patien_id,
unit_name,
grp
order by
patien_id,
start_date,
end_date
| PATIEN_ID | START_DATE | END_DATE | UNIT_NAME |
|-----------|---------------------------|---------------------------|-----------|
| 1 | January, 01 2015 00:00:00 | January, 03 2015 00:00:00 | A |
| 1 | January, 03 2015 00:00:00 | January, 03 2015 00:00:00 | B |
| 1 | January, 03 2015 00:00:00 | January, 07 2015 00:00:00 | C |
| 1 | January, 07 2015 00:00:00 | January, 08 2015 00:00:00 | A |
| 2 | January, 07 2015 00:00:00 | January, 08 2015 00:00:00 | A |
| 2 | January, 08 2015 00:00:00 | January, 09 2015 00:00:00 | B |
注意:如果start_date和end_date中不存储时间部分,且同一天单元间转账较多,则无法确定顺序
发生转移的地方。
我希望你能帮我写下关于病房病人转移的查询。正如你们大多数人所知,患者可以从一个病房转移到另一个病房,也可以从床转移到同一个病房的另一张床,但对于这个查询,我只想 病房转移并且有每个不同单元中每次接送的首次到达和最后更新,并忽略任何床到床的接送,这里是一个例子:
PATIENT_ID Start_Date END_DATE UNIT_NAME BED_NUMBER
----------------------------------------------------------
1 01/01/2015 01/02/2015 A 1
1 01/02/2015 01/03/2015 A 2
1 01/03/2015 01/03/2015 B 1
1 01/03/2015 01/04/2015 C 5
1 01/04/2015 01/06/2015 C 8
1 01/06/2015 01/07/2015 C 9
1 01/07/2015 01/08/2015 A 1
输出应该是:
PATIENT_ID Start_Date END_DATE UNIT_NAME
------------------------------------------------
1 01/01/2015 01/03/2015 A
1 01/03/2015 01/03/2015 B
1 01/03/2015 01/07/2015 C
1 01/07/2015 01/08/2015 A
请注意,患者转移可以在同一天进行多次。
这是 gaps-and-islands problem. You can use Tabibitosan 的方法。完整参考 link 这个方法的解释。
Oracle 11g R2 架构设置:
create table hospi(
patien_id number,
start_date date,
end_date date,
unit_name varchar2(1),
bed_number number
);
insert into hospi values(1, date'2015-01-01', date'2015-01-02', 'A', 1);
insert into hospi values(1, date'2015-01-02', date'2015-01-03', 'A', 2);
insert into hospi values(1, date'2015-01-03', date'2015-01-03', 'B', 1);
insert into hospi values(1, date'2015-01-03', date'2015-01-04', 'C', 5);
insert into hospi values(1, date'2015-01-04', date'2015-01-06', 'C', 8);
insert into hospi values(1, date'2015-01-06', date'2015-01-07', 'C', 9);
insert into hospi values(1, date'2015-01-07', date'2015-01-08', 'A', 1);
insert into hospi values(2, date'2015-01-07', date'2015-01-08', 'A', 1);
insert into hospi values(2, date'2015-01-08', date'2015-01-08', 'B', 1);
insert into hospi values(2, date'2015-01-08', date'2015-01-09', 'B', 1);
查询:
select
patien_id,
min(start_date) start_date,
max(end_date) end_date,
unit_name
from (
select
patien_id,
start_date,
end_date,
unit_name,
row_number() over (partition by patien_id order by start_date, end_date) -
row_number() over (partition by patien_id, unit_name order by start_date, end_date) grp
from hospi
)
group by
patien_id,
unit_name,
grp
order by
patien_id,
start_date,
end_date
| PATIEN_ID | START_DATE | END_DATE | UNIT_NAME |
|-----------|---------------------------|---------------------------|-----------|
| 1 | January, 01 2015 00:00:00 | January, 03 2015 00:00:00 | A |
| 1 | January, 03 2015 00:00:00 | January, 03 2015 00:00:00 | B |
| 1 | January, 03 2015 00:00:00 | January, 07 2015 00:00:00 | C |
| 1 | January, 07 2015 00:00:00 | January, 08 2015 00:00:00 | A |
| 2 | January, 07 2015 00:00:00 | January, 08 2015 00:00:00 | A |
| 2 | January, 08 2015 00:00:00 | January, 09 2015 00:00:00 | B |
注意:如果start_date和end_date中不存储时间部分,且同一天单元间转账较多,则无法确定顺序 发生转移的地方。