Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用日期间隔创建SQL组_Sql_Oracle_Group By_Aggregate_Aggregate Functions - Fatal编程技术网

如何使用日期间隔创建SQL组

如何使用日期间隔创建SQL组,sql,oracle,group-by,aggregate,aggregate-functions,Sql,Oracle,Group By,Aggregate,Aggregate Functions,我有以下疑问: SELECT patient_id FROM patient_visit where visit_type in ('A', 'B', 'C') group by patient_id having count(*) >= 2 获取至少两次“a”、“B”或“C”类就诊的所有患者的列表 “患者就诊表”还有一个“就诊日期”列,用于存储就诊日期。我的问题:是否可以在不删除group by语句的情况下修改上述查询,以查询至少两次就诊的所有患者,以及其中任何一次就诊间隔为60

我有以下疑问:

 SELECT patient_id FROM patient_visit where visit_type in ('A', 'B', 'C') 
 group by patient_id having count(*) >= 2
获取至少两次“a”、“B”或“C”类就诊的所有患者的列表

“患者就诊表”还有一个“就诊日期”列,用于存储就诊日期。我的问题:是否可以在不删除group by语句的情况下修改上述查询,以查询至少两次就诊的所有患者,以及其中任何一次就诊间隔为60 天数

谢谢


注:我正在使用Oracle,如果有内置功能,我也可以使用

我没有oracle要测试,但我认为这会起作用

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'

我没有甲骨文测试,但我认为这将工作

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'

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

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

这是一个昂贵的查询,有点像3。Oracle LAG版本可能更快。

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

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
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
如果你是说连续,那么

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

这是一个昂贵的查询,有点像3。Oracle LAG版本可能更快。

您可能指的是这两次连续访问中的任何一次,而不仅仅是这两次访问中的任何一次,即您不是在寻找一个使用MAX和Min的答案。为什么限制保留组?@Martin最好是任意两次dates@Shannon我有这个限制,因为这个语句是通过XML到SQL编译器。保留Group by语句将使其成为代码生成器的一个简单更改。您可能是指这两次连续访问中的任何一次,而不仅仅是这两次访问中的任何一次,即,您不是在寻找一个使用MAX和MIN的答案。为什么保留Group by的限制?@Martin最好是任意两次dates@Shannon我有这个限制是因为此语句是通过XML到SQL编译器生成的代码。保留Group by语句将使其成为对代码生成器的简单更改。首先,如果未通过子查询返回,则无法选择on DATEFILD。其次,如果未通过子查询返回,则无法选择on DATEFILD。
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