Выбор самой последней даты - PullRequest
0 голосов
/ 31 августа 2018

У меня есть данные, структурированные так:

ID | Enrolment_Date | Appointment1_Date | Appointment2_Date | .... | Appointment150_Date |
112  01/01/2015       01/02/2015          01/03/2018                 01/08/2018    
113  01/06/2018       01/07/2018          NULL                       NULL
114  01/04/2018       01/05/2018          01/06/2018                 NULL

Мне нужна новая переменная, которая подсчитывает количество месяцев между enrolment_date и самой последней встречей. Проблема в том, что у всех людей разное количество назначений.

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

Ответы [ 4 ]

0 голосов
/ 31 августа 2018

Как вы заметили, у вас плохая структура данных. Вы действительно один стол с одной строкой на встречу. В конце концов, что происходит после 150-го приема?

select t.id, t.Enrolment_Date,
       datediff(month, t.Enrolment_Date, m.max_Appointment_Date) as months_diff
from t cross apply
     (select max(Appointment_Date) as max_Appointment_Date
      from (values (Appointment1_Date),
                   (Appointment2_Date),
                   . . .
                   (Appointment150_Date)
           ) v(Appointment_Date)
     ) m;
0 голосов
/ 31 августа 2018

Лучше, если вы сможете создать две таблицы.

Таблица регистрации (dbo.Enrolments)

ID   |   EnrolmentDate

1    | 2018-08-30

2    | 2018-08-31

Таблица встреч (dbo.Appointments)

ID | EnrolmentID | AppointmentDate
1  | 1           | 2018-09-02
2  | 1           | 2018-09-03 
3  | 2           | 2018-09-01
4  | 2           | 2018-09-03

Тогда вы можете попробовать что-то вроде этого.

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

SELECT E.ID, E.EnrolmentDate, A.NoOfMonths
FROM dbo.Enrolments E
OUTER APPLY
(
  SELECT DATEDIFF(mm, E.EnrolmentDate, MAX(A.AppointmentDate)) AS NoOfMonths
  FROM dbo.Appointments A
  WHERE A.EnrolmentId = E.ID
) A

И, если вы хотите подсчитать месяцы с даты регистрации до ближайшей даты встречи, используйте запрос ниже.

SELECT E.ID, E.EnrolmentDate, A.NoOfMonths
FROM dbo.Enrolments E
OUTER APPLY
(
  SELECT DATEDIFF(mm, E.EnrolmentDate, MIN(A.AppointmentDate)) AS NoOfMonths
  FROM dbo.Appointments A
  WHERE A.EnrolmentId = E.ID
) A

Попробуйте это на sqlfiddle

0 голосов
/ 31 августа 2018

Поскольку ОП в настоящее время застрял с этим плохим дизайном, я укажу временное решение. Как и предполагали другие, вы действительно должны изменить структуру здесь. Пока этого будет достаточно:

SELECT '['+ NAME + '],' FROM sys.columns WHERE OBJECT_ID = OBJECT_ID ('TableA') -- find all columns, last one probably max appointment date

SELECT ID, 
      Enrolment_Date, 
      CASE WHEN Appointment150_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment150_Date)
           WHEN Appointment149_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment149_Date)
           WHEN Appointment148_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment148_Date)
           WHEN Appointment147_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment147_Date)
           WHEN Appointment146_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment146_Date)
           WHEN Appointment145_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment145_Date)
           WHEN Appointment144_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment144_Date) -- and so on
      END AS NumberOfMonths
 FROM TableA

Это очень уродливое временное решение, и его следует рассматривать как таковое.

0 голосов
/ 31 августа 2018

Вам нужно будет реструктурировать ваши данные, данная структура плохого дизайна базы данных.
Создайте две отдельные таблицы - одну, называемую пользователями, и другую, называемую встречами. Таблица users содержит идентификатор пользователя, дату регистрации и любую другую конкретную информацию о пользователе. Каждая строка в таблице встреч содержит уникальный идентификатор пользователя и конкретную дату встречи. Структурирование ваших таблиц таким образом облегчит написание запроса, чтобы получить дни / месяцы с момента последней встречи.
Например:

Users Table: 

ID, Enrollment_Date
1, 2018-01-01 
2, 2018-03-02
3, 2018-05-02

Appointments Table: 

ID, Appointment_Date
1, 2018-01-02
1, 2018-02-02
1, 2018-02-10
2, 2018-05-01

После этого вы сможете написать запрос, чтобы объединить две таблицы и вычислить разницу между датой регистрации и минимальным значением даты встречи.

...