Фильтровать записи по дате, чтобы получить последние 7 дней

Я новичок в SQL и пытаюсь создать запрос, который будет учитывать запись, если она соответствует нескольким параметрам. Одним из них является то, что он должен быть введен в течение последних 7 дней, остальные параметры запроса работают нормально, но в тот момент, когда я добавляю И для диапазона дат, он ломается. кто-нибудь может помочь? Вот мой запрос, поле даты — pvs.last_reading, а формат — 2019-06-24 16:20:00.

SELECT  count(*) as criticalCases
  FROM patient_vitals_state pvs
  INNER JOIN user u on u.uuid = pvs.patient_uuid
  WHERE EXISTS (
    SELECT pc.clinic_uuid FROM patient_clinics pc
      WHERE pc.clinic_uuid IN (?) AND pc.patient_uuid = u.uuid
    )
  AND pvs.avg_sbp >= 181
  AND pvs.last_reading BETWEEN NOW() - INTERVAL 7 DAY AND NOW()

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

Caius Jard 24.06.2019 20:54

Прямо сейчас, если я удалю последнее И, запрос будет работать нормально и вернет несколько результатов. Если я добавлю его, он вернет 0, когда должен вернуть 1.

ChrisK 24.06.2019 21:06

Вот все значения ячеек, на которые он должен смотреть. 2019-06-24 16:20:00, 2019-06-01 19:00:00, 2019-06-24 14:00:00, 2019-06-20 18:25:00 это другое поле pvs.avg_sbp который оценивается, и только значение freading в первой строке соответствует критериям.

ChrisK 24.06.2019 21:11

SQL выглядит хорошо; честно говоря, я предполагаю, что у вас есть граничное условие; вы можете проверить это, изменив «7» на, скажем, «14», «90» или «365» и посмотрев, сколько результатов вы получите; это покажет вам, что SQL в порядке, тогда вы можете сосредоточиться на данных; поскольку данные представляют собой даты, вам необходимо учитывать такие вещи, как время сервера (не обязательно такое же, как время вашего рабочего стола), часовой пояс и т. д.

landru27 24.06.2019 21:14

«критерию соответствует только считывание в первой строке» ... что вы имеете в виду под этим? freading не является критерием в вашем SQL

landru27 24.06.2019 21:17

Вот что-то действительно странное, если я изменяю Интервал с 7 на 30, он тянет и считает запись на 01.06.2019, но не запись на сегодня 24.06.2019??

ChrisK 24.06.2019 21:20

Извините, landru27, что надо было "читать". в основном у меня 1 запись в системе. он должен быть не старше 7 дней и иметь рейтинг avg_sbp 181 или выше.

ChrisK 24.06.2019 21:23

ваш комментарий о том, что вы не возвращаете запись на сегодня, сильно напоминает мне о временах, когда я сталкивался с проблемами границы даты; вы можете начать устранение неполадок, увидев результаты SELECT NOW();; может быть, время на сервере SQL отличается от того, что вы думаете? и не удивляйтесь, если завтра вы начнете видеть строку за 6/24; Я на 99,44% уверен, что вы столкнулись с проблемой границы даты и времени.

landru27 24.06.2019 21:33

Итак, идем вперед, я решаю проблему с границей, которую только что запустил. SELECT DATE_SUB(NOW(), INTERVAL 7 DAY) as One_Week_Ago. и вывод был «{One_Week_Ago: 2019-06-17T12:50:20.000Z}». Это правильная дата, так почему же она все еще сбивается?

ChrisK 24.06.2019 21:52

обратите внимание на время вашего результата недельной давности: 12:50; строка данных, которую вы ожидаете увидеть, имеет время 16:20; таким образом, на сервере, на котором работает MySQL, NOW() по-прежнему до — дата и время строки, которую вы ожидаете увидеть; кроме того, Z во временной части результата недельной давности говорит мне, что это несоответствие во многом связано с предположениями о часовом поясе.

landru27 24.06.2019 21:58

Спасибо всем, что я понял это, вместо простого NOW() мне пришлось запустить фильтр как BETWEEN DATE_SUB(NOW(), INTERVAL 7 DAY) AND DATE_ADD(NOW(), INTERVAL 1 DAY) для учета разницы в TimeZone.

ChrisK 24.06.2019 22:10

Я превратил наш разговор в этих комментариях в ответ; именно то, как с этим справиться, зависит от нескольких факторов - слишком много, чтобы предлагать конкретные шаги, - но по этой теме есть достаточно материалов для чтения (часовые пояса в столбцах базы данных), и лучший подход будет зависеть от вашей конкретной ситуации

landru27 24.06.2019 22:12
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
12
409
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это проблема границы даты и времени. SQL в порядке. Согласно нашему разговору в комментариях, строка данных, которую вы ожидаете увидеть, имеет дату и время:

2019-06-24 16:20:00

но на основе вашего запроса недельной давности дата и время на сервере (на момент написания этого) ближе к:

2019-06-24 12:50:20

Таким образом, NOW() является до значением patient_vitals_state.last_reading, и SQL на самом деле делает именно то, что и ожидалось: он исключает результат, чей last_reading находится за пределами BETWEEN параметров.

Z в опубликованном вами результате One_Week_Ago: 2019-06-17T12:50:20.000Z в первую очередь говорит мне о том, что сервер MySQL хранит дату и время в формате UTC, но вы основываете свои ожидаемые результаты на своем собственном локальном времени. Возможно, вы также вводите время, используя свое собственное местное время, но по незнанию они хранятся в формате UTC, таким образом, отображая момент времени, отличный от того, что вы действительно намеревались.

Проблемы с часовым поясом — очень распространенный класс проблем при работе с датами и временем; часовой пояс, используемый для столбца базы данных, является одним из аспектов этой общей проблемы.

Чтобы решить эту проблему, вам необходимо синхронизировать то, как данные даты и времени вводятся, сохраняются и извлекаются из базы данных. На эту тему можно многое прочитать - слишком много, чтобы опубликовать ответ SO. Но, надеюсь, это объясняет источник проблемы и направляет вас к чтению, которое вам нужно сделать, чтобы понять фундаментальный вопрос.

Одно из возможных решений:

SELECT  count(*) as criticalCases
  FROM patient_vitals_state pvs
   JOIN user u 
    on u.uuid = pvs.patient_uuid
  WHERE EXISTS (
    SELECT pc.clinic_uuid 
     FROM patient_clinics pc
      WHERE pc.clinic_uuid IN (?) 
    AND pc.patient_uuid = u.uuid
    )
  AND pvs.avg_sbp >= 181
  AND pvs.last_reading BETWEEN DATE_SUB(NOW(), INTERVAL 7 DAY) 
    AND DATE_ADD(NOW(), INTERVAL 1 DAY);

гм, ... я вижу, как добавление дня к вашему диапазону дат дает вам нужные данные, но это решение, вероятно, подведет вас в какой-то момент; MySQL предлагает средства для работы с несоответствием между часовым поясом сервера и часовым поясом клиента; Я призываю вас прочитать эту тему, потому что доступны более надежные решения; например, у вас фактически есть будущие даты и время в ваших данных - вы действительно хотите сохранить в качестве значения last_reading момент времени, который еще не произошел?

landru27 24.06.2019 22:16

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

landru27 24.06.2019 22:26

Другие вопросы по теме