source

표 a의 각 레코드에 대해 표 b의 NOW()에 가장 가깝지만 그보다 큰 날짜를 가진 레코드를 반환합니다.

itover 2022. 12. 21. 22:30
반응형

표 a의 각 레코드에 대해 표 b의 NOW()에 가장 가깝지만 그보다 큰 날짜를 가진 레코드를 반환합니다.

서버 버전: 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

향후 약속이 있는 참가자만 받고, 향후 약속 장소가 모바일 로케이션일 경우에만 그 참가자를 반송하고 싶습니다.하지만 나는 그들이 가장 가까운 미래의 약속 장소에만 신경을 쓴다.한 번의 질문으로 이 작업을 수행해야 합니다.나는 이 단계에 도달했고, 그곳에서 나는 위치를 얻을 수 있다.모든 장소의 종류, 지금보다 더 큰 모든 예약에 대해 모든 사람을 대상으로 합니다만, 앞으로는 가까운 예약에만 한정하고 어떻게 진행해야 할지 모르겠습니다.

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'
    )
);

MariaDB 10.3은 Window Functions를 지원합니다.따라서 한 가지 방법은 단순히 요건에 따라 테이블을 결합하고 다음 중 하나의 오름차순으로 행 번호를 계산하는 것입니다.beginDateTime그 후 결과를 서브쿼리로 사용하여 행 번호가 1인 행만 검토할 수 있습니다.

ROW_NUMBER() OVER(PARTITION BY p.participantID ORDER BY a.beginDateTime ASC): 모든 행을 같은 값으로 분할합니다.p.participantID가치. 이건 마치GROUP BY하지만 여기서 가장 큰 차이점은GROUP BY는 그것들을 1개의 행으로 집약합니다.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

언급URL : https://stackoverflow.com/questions/58296382/return-the-record-with-the-date-closest-to-but-greater-than-now-now-in-table-b

반응형