Как сделать группу SQL с пробелом - PullRequest
0 голосов
/ 15 марта 2011

У меня следующий запрос:

 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, в котором хранится дата посещения. Мой вопрос: можно ли изменить вышеупомянутый запрос, БЕЗ удаления группы по утверждению, чтобы запросить «всех пациентов, по крайней мере, с двумя посещениями И где любой из этих двух визитов имел разрыв 60 количество дней "?

Спасибо!

P.S .: Я использую Oracle, если есть встроенная функция, я тоже могу ее использовать.

Ответы [ 3 ]

3 голосов
/ 15 марта 2011

Любые две даты, так что первое и последнее посещения будут квалифицированы?

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 (N 3 ).Версия Oracle LAG может быть быстрее.

1 голос
/ 15 марта 2011
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
0 голосов
/ 15 марта 2011

У меня нет оракула для тестирования, но я думаю, что это будет работать

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'
...