2014-09-25 2 views
0

자전거 포크에서 마일 수를 찾기 위해 쿼리를 작성하려고합니다. 이 숫자는 distance_reading을 포크를 설치 한 날짜 (Bicycle_Fork 레코드와 연결된 Bicycle_Fork.start_date 또는 그 이후의 최소 reading_date)와 연결하고 포크를 제거한 날짜 (최대 reading_date 또는에서)를 빼서 계산합니다. Bicycle_Fork.end_date 앞에 있거나, null 인 경우 오늘 날짜와 가장 가까운 값). 적절한 범위로 odometer_reading의 범위를 제한 할 수 있었지만 포크가 설치되었을 때를 나타내는 각 주행 거리계의 최소 및 최대 날짜를 찾는 방법을 알아낼 수 없습니다. start_date 또는 end_date과 일치하는 레코드 만 살펴 봐야했지만 쉽습니다. 사용자는 부품이 변경된 날짜마다 새로운 주행 기록계를 입력 할 필요가 없습니다. 지금까지 몇 시간 동안이 쿼리를 작업 해왔고 모든 결과에서 단일 가장 작은 날짜를 가져 가지 않는 MIN()을 사용할 방법을 찾을 수 없습니다.MySQL이 다른 테이블의 레코드와 관련된 최소 및 최대 날짜를 찾습니다.

질문 : 어떻게 최소 reading_dateodometer_id와 관련된 최대 reading_date 찾을 수 내 WHERE 절에 의해 생성 된 제한을 유지하면서?

이것이 가능하지 않다면 첫 번째 쿼리에서 가져온 값을 PHP의 배열에 저장하고 거기에서 처리 할 계획입니다. 그러나 MySQL에서만 솔루션을 찾고 싶습니다. 여기

데이터베이스 스키마가있는 SQL 바이올린과 쿼리의 현재 상태 : http://sqlfiddle.com/#!2/015642/1

SELECT OdometerReadings.distance_reading, OdometerReadings.reading_date, 
OdometerReadings.odometer_id, Bicycle_Fork.fork_id 
    FROM Bicycle_Fork 
    INNER JOIN (Bicycles, Odometers, OdometerReadings) 
    ON (Bicycles.bicycle_id = Bicycle_Fork.bicycle_id 
    AND Odometers.bicycle_id = Bicycles.bicycle_id AND OdometerReadings.odometer_id = Odometers.odometer_id) 
    WHERE (OdometerReadings.reading_date >= Bicycle_Fork.start_date) AND 
    ((Bicycle_Fork.end_date IS NOT NULL AND OdometerReadings.reading_date<= Bicycle_Fork.end_date) XOR (Bicycle_Fork.end_date IS NULL AND OdometerReadings.reading_date <= CURRENT_DATE())) 

이 계정에 데이터베이스의 가능성을 고려하지 않은 기존의 쿼리가 기록을 결여된다 나는 결국 하나 개의 번호로 다음을 요약합니다,하지만 난 별도로 그들과 함께 일한지 막 '에 : 나는 SQL 스키마에서 반환하는 다음과 같은 것이 얻으려고

SELECT MaxReadingOdo.distance_reading, MinReadingOdo.distance_reading 
FROM 
(SELECT OdometerReadings.distance_reading, OdometerReadings.reading_date, 
OdometerReadings.odometer_id 
    FROM Bicycle_Fork 
    LEFT JOIN (Bicycles, Odometers, OdometerReadings) 
    ON (Bicycles.bicycle_id = Bicycle_Fork.bicycle_id 
    AND Odometers.bicycle_id = Bicycles.bicycle_id AND OdometerReadings.odometer_id = Odometers.odometer_id) 
    WHERE Bicycle_Fork.start_date = OdometerReadings.reading_date) AS MinReadingOdo 
INNER JOIN 
    (SELECT OdometerReadings.distance_reading, OdometerReadings.reading_date, 
    OdometerReadings.odometer_id 
    FROM Bicycle_Fork 
    LEFT JOIN (Bicycles, Odometers, OdometerReadings) 
    ON (Bicycles.bicycle_id = Bicycle_Fork.bicycle_id AND Odometers.bicycle_id 
    = Bicycles.bicycle_id AND OdometerReadings.odometer_id = Odometers.odometer_id) 
    WHERE Bicycle_Fork.end_date = OdometerReadings.reading_date) AS 
    MaxReadingOdo 
ON MinReadingOdo.odometer_id = MaxReadingOdo.odometer_id 

을 다음 시작일 또는 종료일에 맞습니다 .. 값을 확인하는 것이 더 쉽습니다.

min_distance_reading | max_distance_reading | odometer_id 
============================================================= 
75.5     | 2580.5    | 1 
510.5     | 4078.5    | 2 
17.5     | 78.5     | 3 
+0

당신이 좋아하는 경우에,이 2 단계의 간단한 과정 다음 사항을 고려 조치 : 1. 아직 수행하지 않은 경우, 문제점을보다 쉽게 ​​복제 할 수 있도록 적절한 DDL (및/또는 sqlfiddle)을 제공하십시오. 2. 아직 수행하지 않았다면 1 단계에서 제공된 정보와 일치하는 원하는 결과 세트를 제공하십시오. – Strawberry

+0

제안 해 주셔서 감사합니다. SQL 바이올린과 원하는 결과 세트를 추가했습니다. – FlyingMolga

답변

2
내가 퍼즐의 마지막 부분을 이해하지 않지만,이 가까이 보인다

...

SELECT MIN(ro.distance_reading) min_val 
    , MAX(ro.distance_reading) max_val 
    , ro.odometer_id 
    FROM OdometerReadings ro 
    JOIN odometers o 
    ON o.odometer_id = ro.odometer_id 
    JOIN Bicycle_Fork bf 
    ON bf.bicycle_id = o.bicycle_id 
    AND bf.start_date <= ro.reading_date 
GROUP 
    BY ro.odometer_id; 

http://sqlfiddle.com/#!2/015642/8

관련 문제