Выберите максимальное значение в диапазоне дат
Задача:
- Добавьте / отредактируйте текущий рабочий код ниже, чтобы получить только одну строку на пациента, максимальное значение
d1_10.xtransfer
(тип данных int) с ограничением, что этот рядd1_10.dstartdate <= glob_End_Date
,
Предостережения:
Есть похожие вопросы о Stackru и его дочерних сайтах. Ничто из того, что я нашел, не помогло решить эту проблему.
Это медицинская база данных EHR, я могу поделиться кодом, но любое обсуждение результатов должно быть общим и исключать информацию о пациенте.
Я заменяю SQL-запрос в уже существующей электронной таблице Excel, чтобы сделать что-то другое. Excel извлекает информацию из нашей базы данных через соединение ODBC. Наша база данных использует Ingres SQL, который принимает большинство, но не все, ваши типичные разновидности кода SQL. Вполне возможно, что фрагмент кода будет работать в других вариантах SQL, но не с сочетанием Ingres и Excel. У меня есть электронная таблица, работающая и возвращающая результаты, теперь я собираюсь внести некоторые исправления, написав код SQL, который работает в этом программном обеспечении.
До сих пор:
С текущим рабочим кодом ниже (не максимум d1_10.xtransfer
ограничения) мы возвращаем все строки с d1_10.dstartdate
в выбранном пользователем диапазоне дат и с выбранным пользователем d1_10.xinstitute
, Мы хотим только самый последний. То есть ряд пациента с максимальным d1_10.dstartdate
в пределах диапазона дат или максимального d1_10.xtransfer
(индекс, который считает, как они добавляются) в диапазоне дат.
Текущий рабочий код:
"SELECT " & _
"d1.xpid ""XPID"", " & _
"d0_v1.name_family ""NAME_FAMILY"", " & _
"d0_v1.name_given1 ""NAME_GIVEN1"", " & _
"d0_v1.name_given2 ""NAME_GIVEN2"", " & _
"d1.sex ""SEX"", " & _
"d1.birthdate ""DOB"", " & _
"d0_v1.hsp_pid, " & _
"c58.brief_name, " & _
"c73.cname, " & _
"date_trunc('day',d1_10.dstartdate) ""DSTARTDATE"", " & _
"date_trunc('day',d1_17.ddeath) ""DDEATH"" " & _
"FROM d1 " & _
"JOIN d0_v1 ON d1.xpid = d0_v1.xpid " & _
"JOIN d1_2 ON d1.xpid = d1_2.xpid " & _
"JOIN c58 ON d1_2.xmodality = c58.xcmodality " & _
"JOIN d1_10 ON d1.xpid = d1_10.xpid " & _
"JOIN c73 ON d1_10.xinstitute = c73.xcsite " & _
"JOIN d1_17 ON d1.xpid = d1_17.xpid " & _
"WHERE " & _
"d1_10.xinstitute = " & institute_index & " AND " & _
"d1_10.dstartdate >= '" & glob_Start_Date & " 00:00:00' and " & _
"d1_10.dstartdate <= '" & glob_End_Date & " 23:59:59' "
Наиболее близкий я получил код, запускаемый из таблицы Excel, с этой дополнительной строкой в предложении WHERE:
d1_10.xtransfer = (SELECT MAX(d1_10.xtransfer) FROM d1_10 GROUP BY xpid)
С помощью этой дополнительной строки мы теперь возвращаем только одну строку от каждого пациента, у которого есть d1_10.xtransfer
в диапазоне дат. Но если у них есть ряд, где d1_10.xtransfer
более поздний, чем диапазон дат, тогда они вообще не отображаются в результатах.
С этой строкой код принимает MAX(d1_10.xtransfer)
для каждого xpid, прежде чем он применяет ограничение даты. По моей логике мы хотим, чтобы это делалось после этого, но я не смог придумать код, который запускает его, который приближается к этому.
Заранее спасибо. Я буду держать этот вопрос обновленным с дополнительной информацией ниже этого разрыва страницы.
Дополнительная информация:
- Per PaulM:
Да, xpid
это идентификационный номер пациента, уникальный для каждого пациента.
Добавлена / отредактирована строка в предложении WHERE для: "d1_10.xtransfer = (SELECT MAX(xtransfer) FROM d1_10 d1_10_b WHERE d1_10.xpid = d1_10_b.xpid AND d1_10_b.dstartdate <= '" & glob_End_Date & " 23:59:59') "
Пациенты Боб имеют переводы 14 и 17 июня, которые соответствуют остальным критериям.
При вводе диапазона дат с конечной датой 17 июня + электронная таблица правильно возвращает строку для Боба с его передачей 17 июня.
При вводе диапазона дат с конечной датой 14,15 или 16 июня электронная таблица неправильно возвращает строку для Боба.
Кажется, что он все еще принимает максимальный ransransfer, прежде чем ограничить по дате.
- Согласно комментарию PaulM:
Я выполнил выборку для конкретного пациента следующим образом:
Входные данные:
SELECT MAX(xtransfer) FROM d1_10 d1_10_b WHERE d1_10_b.xpid = '2258' AND d1_10_b.dstartdate <= '20-apr-2016 23:59:59'
Он вывел значение MAX(xtransfer) = '48233'
, Это правильно
Таким образом, при запуске в Visual SQL как собственное утверждение, настройка d1_10_b.xpid
равный конкретному пациенту, он правильно извлекает максимальный перевод из диапазона дат. (Был более недавний xtransfer
за пределами диапазона дат, и все равно правильно отображается максимум xtransfer
из диапазона дат.)
Затем я попытался запустить точно такой же отбор в таблице "Где закрыть". То есть я вручную выбрал тот же диапазон дат (который корректно и успешно передается через переменную), но я выбрал d1_10.xpid = d1_10_b.xpid
за d1_10_b.xpid = '2258'
, Это не сработало. Электронная таблица не показала строку для этого пациента, по-видимому, потому что она все еще применяет функцию MAX(), прежде чем она ограничивается диапазоном дат в подзапросе. И тем не менее, подзапрос работает, когда выполняется сам по себе.
Большое спасибо за любые дальнейшие предложения.
1 ответ
Вам нужно добавить ограничение даты в подвыборку, а также основной запрос. Также я подозреваю, что группа неверна. Добавляя группу, вы делаете выбор из списка пациентов xtransfer значений с наибольшим значением для каждого xpid (идентифицирует пациента?). Однако это означает, что если интересующая вас строка из основного запроса имеет значение xtransfer, соответствующее наибольшему, принадлежащему другому xpid, вы получаете ложное совпадение.
Что вам действительно нужно, так это добавить соединение на xpid из подпункта назад в основной запрос. Для этого вам понадобится другое имя корреляции, например
d1_10.xtransfer = (SELECT MAX(xtransfer)
FROM d1_10 d1_10_b
WHERE d1_10.xpid = d1_10_b.xpid
AND d1_10_b.dstartdate > = ... {as above} )