如何创建具有日期间隙的 SQL 组

发布于 2024-10-22 05:52:28 字数 375 浏览 2 评论 0原文

我有以下查询:

 SELECT patient_id FROM patient_visit where visit_type in ('A', 'B', 'C') 
 group by patient_id having count(*) >= 2

获取至少两次就诊的所有患者的列表,类型为“A”、“B”或“C”。

Patient_visit 表还有一个 Visit_date 列,用于存储就诊日期。我的问题:是否可以修改上述查询而不删除 group by 语句来查询“所有至少两次就诊的患者并且其中任何两次就诊的差距为 60 天数”?

谢谢!

PS:我使用的是Oracle,如果有内置函数,我也可以使用它。

I have the following query:

 SELECT patient_id FROM patient_visit where visit_type in ('A', 'B', 'C') 
 group by patient_id having count(*) >= 2

To get a list of all patients that had at least two visits of type 'A', 'B', or 'C'.

The patient_visit table also has a visit_date column which stores the date of the visit. My question: is it possible to modify the above query WITHOUT removing the group by statement to query "all patients with at least two visits AND where any of those two visit had a gap of 60
number of days"?

Thanks!

P.S.: i'm using Oracle, if there's a built-in function, I can use that too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟花易冷人易散 2024-10-29 05:52:28

任意两个日期,第一次和最后一次访问都符合条件吗?

SELECT patient_id
FROM patient_visit
where visit_type in ('A', 'B', 'C') 
group by patient_id
having count(*) >= 2 AND MAX(visit_date) - MIN(visit_date) >= 60

如果您的意思是连续的,那么

SELECT patient_id
FROM patient_visit
where visit_type in ('A', 'B', 'C') 
  AND EXISTS (
    select *
    from patient_visit v
    where v.visit_type in ('A', 'B', 'C')
      and v.patient_id = patient_visit.patient_id
      and v.visit_date >= patient_visit.visit_date + 60)
  AND NOT EXISTS (
    select *
    from patient_visit v2
    where v2.visit_type in ('A', 'B', 'C')
      and v2.patient_id = patient_visit.patient_id
      and v2.visit_date > patient_visit.visit_date
      and v2.visit_date < patient_visit.visit_date + 60)
group by patient_id

这是一个昂贵的查询,其数量级为 O(N3)。 Oracle LAG 版本可能会更快。

Any two dates, so the first and last visits would qualify?

SELECT patient_id
FROM patient_visit
where visit_type in ('A', 'B', 'C') 
group by patient_id
having count(*) >= 2 AND MAX(visit_date) - MIN(visit_date) >= 60

If you meant consecutive, then

SELECT patient_id
FROM patient_visit
where visit_type in ('A', 'B', 'C') 
  AND EXISTS (
    select *
    from patient_visit v
    where v.visit_type in ('A', 'B', 'C')
      and v.patient_id = patient_visit.patient_id
      and v.visit_date >= patient_visit.visit_date + 60)
  AND NOT EXISTS (
    select *
    from patient_visit v2
    where v2.visit_type in ('A', 'B', 'C')
      and v2.patient_id = patient_visit.patient_id
      and v2.visit_date > patient_visit.visit_date
      and v2.visit_date < patient_visit.visit_date + 60)
group by patient_id

This is an expensive query, something of the order O(N3). The Oracle LAG version could be faster.

樱桃奶球 2024-10-29 05:52:28
SQL> create table patient_visit (patient_id number(38) not null
  2      , visit_type varchar2(1) not null
  3      , visit_date date not null);

Table created.

SQL> insert into patient_visit
  2  select 1, 'A', date '2010-01-01' from dual
  3  union all select 1, 'D', date '2010-01-02' from dual
  4      -- ignore, by type
  5  union all select 1, 'C', date '2010-01-01' + 60 from dual
  6      -- 1 is included
  7  union all select 1, 'B', date '2011-01-01' from dual
  8      -- don't include 1 more than once
  9  union all select 2, 'A', date '2010-01-01' from dual
 10  union all select 2, 'B', date '2010-01-02' from dual
 11      -- breaks up 60 day gap.
 12  union all select 2, 'C', date '2010-01-01' + 60 from dual;

7 rows created.

SQL> commit;

Commit complete.

SQL> select patient_id
  2  from (select patient_id
  3          , visit_date
  4          , lag(visit_date) over (partition by patient_id
  5              order by visit_date) prior_visit_date
  6      from patient_visit
  7      where visit_type in ('A', 'B', 'C'))
  8  where visit_date - prior_visit_date >= 60
  9  group by patient_id;

PATIENT_ID
----------
         1

SQL> spool off
SQL> create table patient_visit (patient_id number(38) not null
  2      , visit_type varchar2(1) not null
  3      , visit_date date not null);

Table created.

SQL> insert into patient_visit
  2  select 1, 'A', date '2010-01-01' from dual
  3  union all select 1, 'D', date '2010-01-02' from dual
  4      -- ignore, by type
  5  union all select 1, 'C', date '2010-01-01' + 60 from dual
  6      -- 1 is included
  7  union all select 1, 'B', date '2011-01-01' from dual
  8      -- don't include 1 more than once
  9  union all select 2, 'A', date '2010-01-01' from dual
 10  union all select 2, 'B', date '2010-01-02' from dual
 11      -- breaks up 60 day gap.
 12  union all select 2, 'C', date '2010-01-01' + 60 from dual;

7 rows created.

SQL> commit;

Commit complete.

SQL> select patient_id
  2  from (select patient_id
  3          , visit_date
  4          , lag(visit_date) over (partition by patient_id
  5              order by visit_date) prior_visit_date
  6      from patient_visit
  7      where visit_type in ('A', 'B', 'C'))
  8  where visit_date - prior_visit_date >= 60
  9  group by patient_id;

PATIENT_ID
----------
         1

SQL> spool off
生寂 2024-10-29 05:52:28

我没有要测试的预言机,但我认为这会起作用

select patient_id from 
   (SELECT patient_id, dateField FROM patient_visit where visit_type in ('A','B', 'C') 
   group by patient_id having count(*) >= 2) as temp 
where temp.dateField > '2011-01-01'

I dont have oracle to test but I think this will work

select patient_id from 
   (SELECT patient_id, dateField FROM patient_visit where visit_type in ('A','B', 'C') 
   group by patient_id having count(*) >= 2) as temp 
where temp.dateField > '2011-01-01'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文