2016-01-26 1 views
1

Я хочу добавить дополнительные (отсутствующие) строки в таблицу. Существующая ситуация: у меня есть таблица пациентов, где находится дата регистрации, и я подсчитываю, как долго пациент уже зарегистрирован в течение недель («TimeInProgram»). Теперь я объединяюсь над этим, чтобы получить количество пациентов, которые в настоящее время находятся в этом периоде (см. COUNT -> атрибут «Пациенты»). В итоге я суммирую с помощью оконной функции, чтобы получить количество пациентов, которые уже были в определенный период.SQL: Добавить недостающие строки

SELECT aggregation.*, SUM("Patients") OVER() "All", SUM("Patients") OVER (ORDER BY "TimeInProgram" DESC ROWS UNBOUNDED PRECEDING) "PatientsCounterInTime" FROM (
SELECT COUNT(DISTINCT "PatientID") "Patients", "TimeInProgram" FROM (
SELECT 
    pat."PatientID", 
    ROUND(((DAYS_BETWEEN(pat."RegisteredOnDate", NOW())+1)/7.0), 0, 'ROUND_UP') "TimeInProgram" 
    FROM t_patient pat 
    ORDER BY "PatientID" 
) data 
GROUP BY "TimeInProgram" 
ORDER BY "TimeInProgram" 
) aggregation 

Результат вы можете увидеть здесь:

(PatientsCounterInTime PLUS Patients of the following row is the value of PatientsCounterInTime of the following row.)

PatientsCounterInTime PLUS пациентов следующей строке значение PatientsCounterInTime следующего row.You может увидеть проблему: Есть некоторые " TimeInProgram "не хватает, как неделя 4 или неделя 5, потому что в данный момент ни один пациент не находится в этом периоде. Поэтому я хочу добавить недостающие строки. Значение «PatientsCounterInTime» должно быть 162 в неделю 4, 5 неделя и «Пациенты», конечно, 0.

Я использую базу данных HANA.

С уважением, спасибо.

UPDATE:

SELECT "TiP" "TimeInProgram", "Patients", "PatientsCounterInTime" FROM (
     SELECT aggregation.*, SUM("Patients") OVER() "All", SUM("Patients") OVER (ORDER BY "TimeInProgram" DESC ROWS UNBOUNDED PRECEDING) "PatientsCounterInTime" FROM (
     SELECT COUNT(DISTINCT "PatientID") "Patients", "TimeInProgram" FROM (
     SELECT 
      pat."PatientID", 
      ROUND(((DAYS_BETWEEN(pat."RegisteredOnDate", NOW())+1)/7.0), 0, 'ROUND_UP') "TimeInProgram" 
      FROM "t_patient" pat 
      ORDER BY "PatientID" 
     ) data 
     GROUP BY "TimeInProgram" 
     ORDER BY "TimeInProgram" 
     ) aggregation 
    ) 
    RIGHT JOIN "t_time_in_program" t ON "TimeInProgram" = t."TiP"; 

enter image description here

(PatientsCounterInTime PLUS Пациенты следующей строке значение PatientsCounterInTime следующей строки.)

+2

Вам нужна таблица календаря, содержащая все недели, по существу, один столбец с 1 по 48 и LEFT JOIN на этом – Mihai

+1

В дополнение к тому, что сказал Михай, вам нужно будет использовать LEAD или LAG, чтобы получить последнее время для счетчиков при подключении (SINCE будет иметь нулевое значение после левого соединения) – sagi

+0

Благодарим вас за полезные ответы! Я присоединился к таблице и обновил сообщение выше. Я не уверен, как теперь использовать LEAD/LAG для заполнения данных столбца пропусков. Любой намек снова? @sagi – ScientiaEtVeritas

ответ

0

Вы можете найти таблицы времени в «_SYS_BI "схема. В случае их нет, here - полезная статья

Вот пример использования. Допустим, вы хотите отобразить период с 2000 по текущий год:

WITH dataset AS (
    Select '2016' as YEAR, '216' AS PATIENTS FROM DUMMY 
    union all 
    Select '2010' as YEAR, '200' AS PATIENTS FROM DUMMY 
) 
SELECT 
     distinct tdim.year, 
     case when dataset.PATIENTS is null then 0 else dataset.PATIENTS end 
    FROM "_SYS_BI"."M_TIME_DIMENSION_MONTH" tdim 
left outer join dataset on tdim.year = dataset.year 
where tdim.year >=2000 and tdim.year <= YEAR(CURRENT_DATE) 

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