背景
我们有一个工作查询,用于选择患者(d8_5_B.xpostaccessuse
)患者(任何表格中的xpid
列)在他们约会后90天内使用的访问类型(d1.ddiadate +'90 days'
)
变得慢性(SELECT
d8_B.start_date,
d8_5_B.xpostaccessuse
FROM d1
LEFT JOIN d8 d8_B
ON d1.xpid = d8_B.xpid
LEFT JOIN d8_5 d8_5_B
ON d8_B.xsession_id = d8_5_B.xsession
WHERE
d8_B.start_date IN (
SELECT MAX(d8.start_date)
FROM d8
LEFT JOIN d1
ON d8.xpid = d1.xpid
WHERE d8.start_date <= d1.ddiadate + '90 days'
GROUP BY d8.xpid
)
)。输出是两列:一个日期,一个整数。
查询:
d8_5_B.xpostaccessuse = 3
目标:
我们需要能够确定他们的访问权限是否在这90天期间来回变化。理想情况下,我们也希望能够突出显示切换到的内容以及何时切换,但较小的胜利仍然有用。
d1.ddiadate
上的d8_5_B.xpostaccessuse = 3
。 d1.ddiadate +'90 days'
上的3
。但是,如果他们的访问权限从5
更改为3
并在此90天范围内再次更改为3
,我们无法确定其不是{{1}一直以来。
我们如何确定:
3
更改为其他内容并返回3
在这90天期间?到目前为止工作:
到目前为止,我们最好的想法是使用count()
聚合来计算日期范围内的总行数,然后计算d8_5_B.xpostaccessuse = 3
的行数并比较结果。这将告诉我们是否存在不连续性,即使它不是什么。我们无法使用此方法,主要是由于所需的group by
。
我们的另一个想法是尝试选择不同的值d8_5_B.xpostaccessuse
和group by xpid
,但同样的问题出现在group by
上。
更新
样本表(以下为G琼斯):
create table d1
(xpid integer, ddiadate ingresdate);
create table d8
(xpid integer, xsession_id integer, start_date ingresdate);
create table d8_5
(xpid integer, xsession integer, xpostaccessuse integer);
insert into d1 values(1, '2018-01-01');
insert into d1 values(2, '2018-01-01');
insert into d8 values(1, 1, '2018-01-01');
insert into d8 values(1, 2, '2018-01-10');
insert into d8 values(1, 3, '2018-01-20');
insert into d8 values(2, 1, '2018-01-01');
insert into d8 values(2, 2, '2018-01-10');
insert into d8 values(2, 3, '2018-01-20');
insert into d8_5 values(1, 1, 3);
insert into d8_5 values(1, 2, 3);
insert into d8_5 values(1, 3, 3);
insert into d8_5 values(2, 1, 3);
insert into d8_5 values(2, 2, 5);
insert into d8_5 values(2, 3, 3);
与此任务相关的表格定义:
d1:人口统计表/基本患者信息
d1.xpid
)d1.ddiadate
)d8:会话表
d8.xsession_id
)d8.xpid
)d8.start_date
)d8_5:具有访问数据的会话子表
d8_5.xsession
)d8_5.xpid
)d8_5.xpostaccessuse
)请注意,所有三个表都可以在xpid
和d8.xsession_id = d8_5.xsession
答案 0 :(得分:1)
您可能需要select COUNT(DISTINCT d8_5_B.xpostaccessuse)
后使用group by
来显示患者的状态。
如果您想要完整的请求,请提供数据测试和创建表;)
编辑:
这可能会显示90天内的不同访问次数(我使用INNER JOIN
,因为看起来你的左边没用了)
SELECT
d8.start_date,
d5.xpostaccessuse,
d1.access_count
FROM (
SELECT
d8.xpid,
MAX(d8.start_date) date_max,
COUNT(DISTINCT d5.xpostaccessuse) access_count
FROM d8
INNER JOIN d1
ON d8.xpid = d1.xpid
INNER JOIN d8_5 d5
ON d8.xsession_id = d5.xsession
WHERE
d8.start_date > d1.ddiadate
AND d8.start_date <= d1.ddiadate + '90 days'
GROUP BY d8.xpid
) d1
INNER JOIN d8
ON d1.xpid = d8.xpid
AND d8.start_date = d1.date_max
INNER JOIN d8_5 d5
ON d8.xsession_id = d5.xsession
答案 1 :(得分:1)
由于这里提到了Ingres,一种可能的方法可能是使用行生成数据库过程来识别哪些行没有改变,并避免返回任何您不感兴趣的行。示例如下所示关于我对表格的看法,希望它有一些用处。
-- Some sample data.
create table d1
(xpid integer, ddiadate ingresdate);
create table d8
(xpid integer, xsession_id integer, start_date ingresdate);
create table d8_5
(xpid integer, xsession integer, xpostaccessuse integer);
insert into d1 values(1, '2018-01-01');
insert into d1 values(2, '2018-01-01');
insert into d8 values(1, 1, '2018-01-01');
insert into d8 values(1, 2, '2018-01-10');
insert into d8 values(1, 3, '2018-01-20');
insert into d8 values(2, 1, '2018-01-01');
insert into d8 values(2, 2, '2018-01-10');
insert into d8 values(2, 3, '2018-01-20');
insert into d8_5 values(1, 1, 3);
insert into d8_5 values(1, 2, 3);
insert into d8_5 values(1, 3, 3);
insert into d8_5 values(2, 1, 3);
insert into d8_5 values(2, 2, 5);
insert into d8_5 values(2, 3, 3);
-- Query to show patient's access type at each session
-- during the 3 months before becoming chronic.
select d1.xpid, d8.start_date, d8_5.xpostaccessuse
from d1
join d8 on d1.xpid = d8.xpid
join d8_5 on d1.xpid = d8_5.xpid and d8.xsession_id = d8_5.xsession
where d8.start_date <= d1.ddiadate + '90 days'
and d8.start_date >= d1.ddiadate
order by xpid, start_date;
-- Use a row-producing database procedure, based on the
-- above query, to return a row only when data changes.
create procedure rpp
result row r (xpid integer, start_date date, xpostaccessuse integer) =
declare
xpid = integer;
sd = ingresdate;
xp = integer;
xplast = integer;
xpidlast = integer;
begin
xplast = -1; xpidlast = -1;
for
select d1.xpid, d8.start_date, d8_5.xpostaccessuse
into :xpid, :sd, :xp
from d1
join d8 on d1.xpid = d8.xpid
join d8_5 on d1.xpid = d8_5.xpid and d8.xsession_id = d8_5.xsession
where d8.start_date <= d1.ddiadate + '90 days'
and d8.start_date >= d1.ddiadate
order by xpid, d8.start_date desc
do
if :xplast != :xp or :xpidlast != :xpid
then
return row(:xpid, :sd, :xp);
xplast = :xp;
xpidlast = :xpid;
endif;
endfor;
end;
-- Query the row-producing procedure.
select * from rpp() order by xpid, start_date;
答案 2 :(得分:0)
在这种SQL风格中,Ingres 9(已经过时,可能与Internet的其余部分无关,但是如果不是……),则在哪里可以使用子查询存在很多限制。
我最终为需要放置在“非法”位置的子查询创建视图,将这些视图作为表加入并获得相同的效果。
祝你好运!