SQL запрос, чтобы найти клиентов, которые заказывают слишком часто? - PullRequest
4 голосов
/ 19 февраля 2009

Моя база данных на самом деле не клиенты и заказы, это клиенты и рецепты для их глазных тестов (на тот случай, если кому-то будет интересно, почему я хочу, чтобы мои клиенты делали заказы реже!)

У меня есть база данных для сети оптиков, в таблице рецептов есть идентификационный номер отделения, идентификационный номер пациента и дата, когда у них были проверены глаза. Со временем у пациентов будет больше, чем один глазной тест, перечисленный в базе данных. Как я могу получить список пациентов, которым рецепт был введен в систему более одного раза в шесть месяцев. Другими словами, если дата одного рецепта указана, например, в течение трех месяцев с даты предыдущего рецепта для того же пациента.

Пример данных:

Branch  Patient DateOfTest
1      1          2007-08-12
1      1          2008-08-30
1      1          2008-08-31
1      2          2006-04-15
1      2          2007-04-12

Мне не нужно знать фактические даты в наборе результатов, и это не обязательно должно быть ровно три месяца, просто список пациентов, у которых рецепт слишком близок к предыдущему рецепту. В приведенных примерах данных я хочу, чтобы запрос возвращал:

Branch   Patient
1       1

Этот тип запроса не будет выполняться очень регулярно, поэтому я не слишком обеспокоен эффективностью. В нашей оперативной базе данных у меня четверть миллиона записей в таблице рецептов.

Ответы [ 5 ]

7 голосов
/ 19 февраля 2009

как то так

select p1.branch, p1.patient
from prescription p1, prescription p2
where p1.patient=p2.patient
and p1.dateoftest > p2.dateoftest
and datediff('day', p2.dateoftest, p1.dateoftest) < 90;

должен сделать ... вы можете добавить

and p1.dateoftest > getdate()

, чтобы ограничить будущие рецепты испытаний.

1 голос
/ 19 февраля 2009

Этот будет эффективно использовать индекс на (Branch, Patient, DateOfTest), который у вас, конечно, должен быть:

SELECT Patient, DateOfTest, pDate
FROM (
  SELECT (
    SELECT TOP 1 DateOfTest AS last
    FROM Patients pp
    WHERE pp.Branch = p.Branch
      AND pp.Patient = p.Patient
      AND pp.DateOfTest BETWEEN DATEADD(month, -3, p.DateOfTest) AND p.DateOfTest
    ORDER BY 
      DateOfTest DESC
    ) pDate
  FROM Patients p
) po
WHERE pDate IS NOT NULL
0 голосов
/ 19 февраля 2009
SELECT Branch
      ,Patient
  FROM (SELECT Branch
              ,Patient
              ,DateOfTest
              ,DateOfOtherTest
          FROM Prescriptions P1
          JOIN Prescriptions P2
            ON P2.Branch = P1.Branch
           AND P2.Patient = P2.Patient
           AND P2.DateOfTest <> P1.DateOfTest
       ) AS SubQuery
  WHERE DATEDIFF(day, SubQuery.DateOfTest, SubQuery.DateOfOtherTest) < 90
0 голосов
/ 19 февраля 2009

автообъединение:

select a.branch, a.patient
   from prescriptions a
   join prescriptions b
   on     a.branch = b.branch 
      and a.patient = b.patient
      and a.dateoftest > b.dateoftest
      and a.dateoftest - b.dateoftest < 180
group by a.branch, a.patient

Это предполагает, что вы хотите, чтобы пациенты посещали одну и ту же ветку дважды. Если нет, выньте часть ответвления.

0 голосов
/ 19 февраля 2009

В пути:

select d.branch, d.patient
from   data d
where exists
( select null from data d1
  where  d1.branch = d.branch
  and    d1.patient = d.patient
  and    "difference (d1.dateoftest ,d.dateoftest) < 6 months"
);

Эта часть нуждается в изменении - я не знаком с операциями даты SQL Server:

"difference (d1.dateoftest ,d.dateoftest) < 6 months"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...