Вернуть запись с датой, ближайшей к, но больше, чем сейчас NOW () в таблице b, для каждой записи в таблице a - PullRequest
1 голос
/ 09 октября 2019

Версия сервера: 10.3.15-MariaDB-log

У меня есть такая структура данных

TABLE A - Participant

participantID
--------------
1
2
3
4

TABLE B - Appointment

appointmentID | participantID | locationID | beginDateTime
----------------------------------------------------------------
1             | 1             | 1          | 2019-10-09 11:00:00
2             | 1             | 1          | 2019-10-10 11:00:00
3             | 2             | 2          | 2019-10-11 11:00:00
4             | 3             | 3          | 2019-11-09 11:00:00
5             | 5             | 1          | 2019-10-15 11:00:00

TABLE C - Location

locationID | locationTypeID
----------------------------
1          | 1
2          | 2
3          | 3

TABLE D - Location Type

locationTypeID | locationType
-----------------------------
1              | mobile
2              | onsite
3              | unknown

Я хочу получить только участников, которые имеютВстреча, которая будет в будущем, и я хочу вернуть этих участников, только если местоположение их будущей встречи - тип мобильного местоположения. Однако я забочусь только о месте их ближайшего будущего назначения. Мне нужно сделать это в одном запросе. Я дошел до этой стадии, где я могу получить locationType всех местоположений, для всех встреч больше, чем сейчас, для всех людей, но мне нужно ограничить это только своим ближайшим собранием в будущем, и я не уверен, какпродолжить.

SELECT p.participantID
FROM locationType AS lt
LEFT JOIN location AS l ON l.locationTypeID = lt.locationTypeID
LEFT JOIN appointment AS a ON a.locationID = l.locationID
LEFT JOIN participant AS p ON p.participantID = a.participantID
WHERE p.participantID IN (
    SELECT a.participantID
    FROM appointment AS a
    LEFT JOIN location AS l ON l.locationID = a.locationID
    LEFT JOIN locationType AS lt ON lt.locationTypeID = l.locationTYpeID
    WHERE a.beginDateTime > NOW()
    AND l.locationTypeID IN (
        SELECT locationTypeID 
        FROM locationType 
        WHERE locationType = 'mobile'
    )
);

1 Ответ

2 голосов
/ 09 октября 2019

MariaDB 10.3 поддерживает Функции окна ;Итак, один из способов - просто объединить таблицы на основе ваших требований, а затем вычислить номер строки в порядке возрастания beginDateTime. После этого вы можете использовать результат как подзапрос и рассматривать только те строки, где номер строки равен 1.

ROW_NUMBER() OVER(PARTITION BY p.participantID ORDER BY a.beginDateTime ASC): он разделяет все строки вместе, имея одинаковое значение p.participantID. Это похоже на GROUP BY, но главное отличие здесь в том, что GROUP BY объединяет их в одну строку, тогда как PARTITION BY поддерживает их как отдельные строки. Теперь в конкретном разделе с определенным значением p.participantID он присваивает номер строки отдельным строкам в порядке возрастания значения beginDateTime. Таким образом, строка с наименьшим значением beginDateTime получает номер строки = 1, второй наименьший - 2 и т. Д. Так как вам нужна ближайшая строка даты и времени, мы можем просто рассмотреть строку с номером строки 1.

SELECT * FROM 
(
  SELECT p.participantID, 
         ROW_NUMBER() OVER(PARTITION BY p.participantID 
                           ORDER BY a.beginDateTime ASC) AS rn
  FROM locationType AS lt
  JOIN location AS l ON l.locationTypeID = lt.locationTypeID
  JOIN appointment AS a ON a.locationID = l.locationID 
                           AND a.beginDateTime > NOW() 
  JOIN participant AS p ON p.participantID = a.participantID 
  WHERE lt.locationType = 'Mobile'
) dt 
WHERE rn = 1
...