2016-01-11 2 views
1

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

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

Окончательная колонка в таблице была добавлена ​​вручную.

Текущие результаты:

enter image description here

SELECT   
PendingRangeSignals.PendingOrderID, 
PendingOrders.PatientID, 
Parameters.ParameterName, 


(SELECT CONVERT(VARCHAR, PendingRangeSignals.StartTime, 103) + ' ' + CONVERT(VARCHAR, DATEPART(hh, PendingRangeSignals.StartTime)) + ':' + RIGHT('0' + CONVERT(VARCHAR, DATEPART(mi, PendingRangeSignals.StartTime)), 2) AS Date) as "Start Time Column", 

(SELECT CONVERT(VARCHAR, RangeSignals.EndTime, 103) + ' ' + CONVERT(VARCHAR, DATEPART(hh, RangeSignals.EndTime)) + ':' + RIGHT('0' + CONVERT(VARCHAR, DATEPART(mi, RangeSignals.EndTime)), 2) AS Date) as "End Time Column", 

iif(datepart(hh,PendingRangeSignals.StartTime)>= 0 OR 

CASE 
    WHEN RangeSignals.EndTime IS NULL 
    THEN datediff(hh,PendingRangeSignals.StartTime,isnull(RangeSignals.EndTime,getdate())) 
    ELSE datediff(hh,PendingRangeSignals.StartTime,RangeSignals.EndTime) 
END < 24, 

datediff(d,iif(PendingRangeSignals.StartTime < DATEADD(month, DATEDIFF(month, 0, getdate()), 0), DATEADD(month, DATEDIFF(month, 0, getdate()), 0),PendingRangeSignals.StartTime) , dateadd(day,1,isnull(RangeSignals.EndTime,getdate()))), 
datediff(d,iif(PendingRangeSignals.StartTime < DATEADD(month, DATEDIFF(month, 0, getdate()), 0), DATEADD(month, DATEDIFF(month, 0, getdate()), 0),PendingRangeSignals.StartTime) , isnull(RangeSignals.EndTime,getdate()))) as "LineDaysinMonth" 

FROM 
PendingRangeSignals INNER JOIN 
PendingOrders ON PendingRangeSignals.PendingOrderID = PendingOrders.PendingOrderID INNER JOIN 
Parameters ON PendingRangeSignals.ParameterID = Parameters.ParameterID 
LEFT JOIN RangeSignals ON RangeSignals.ParameterID = Parameters.ParameterID and RangeSignals.PatientID = PendingOrders.PatientID and PendingRangeSignals.StartTime = RangeSignals.StartTime 

WHERE 
(PendingOrders.PatientID = 2105) and pendingorders.Status = 5 and ((datepart(month,RangeSignals.EndTime) = datepart(month,getdate())) or RangeSignals.EndTime is null) and [Parameters].ParameterID IN (1046, 1372, 8546, 1051, 8532, 8538, 1375, 8531, 8888) 
+0

Учитывая, что у пациента могут быть введены и выведены линии, «дни с линией» не обязательно непрерывны. Я не думаю, что это можно решить с помощью одного запроса. Возможно, вам придется получить все данные, а затем пропустить их, чтобы подсчитать конкретные календарные дни. –

+2

Это, вероятно, будет легче читать (и решать), если вы устраните посторонние вещи (например, pendingorders.Status = 5), чтобы свести к минимуму точно вопрос, который вы пытаетесь решить. Кроме того, было бы полезно упростить структуру таблиц. –

+0

Что значит «когда перекрываются линейные дни»? пожалуйста, покажите образцы таблиц. – koriander

ответ

0

Из того, что я теперь понимаю, я хотел бы предложить:

1) создать таблицу "дней" с номерами 0-31: дни (день)

2) создать подзапрос, который возвращает календарные дни для месяца, который вы хотите, например, упрощенный пример в течение месяцев с 31 днем.

(SELECT cast('2016-01-01' + interval `day` day as date) mydate 
     FROM days) mymonth 

3) присоединиться к вашей записи строки пациентов с этим подзапроса и использовать «отличный», чтобы удалить повторяющиеся даты, например,

SELECT DISTINCT patientid, count(patientid) as `LineDays` 
FROM (SELECT cast('2016-01-01' + interval `day` day as date) mydate 
     FROM days) mymonth 
LEFT JOIN rangesignals on (mydate between startDate and endDate) 
GROUP BY patientid; 

Я упростил время до сих пор и проигнорировал pendingsignals, но я думаю, вы получите эту идею. Я не совсем уверен, что отдельные будут удалять даты опускания до группы (я думаю, нет), но если это так, вы можете сделать это с помощью другого подзапроса. И я думаю, что если вы используете MS-SQL, может быть другой способ сделать календарь. Если вы создадите sqlfiddle, тогда это легко проверить.