简体   繁体   中英

MySQL Limit and Order Left Join

I have two tables: Processes and Validations; p and v respectively. For each process there are many validations.

The aim is to:

  • Retrieve the latest validation for each process.
  • Generate a dynamic date (Due_Date) as to when the next validation is due (being 365 days after the latest validation date).
  • Filter the results to any due dates that fall in the current month.

In short terms; I want to see what processes are due to be validated in the current month.

I'm 99% there with the query code. Having read through some posts on here I'm fairly certain I'm on the right track. My problem is that my query still returns all of the results for each process, instead of the top 1.

FYI: The processes table uses "Process_ID" as a primary key; whereas the Validations Table uses "Validation_Process_ID" as a foreign key.

Code at present :

Select p.Process_ID,
p.Process_Name,
v.Validation_Date,
Date_Add(v.Validation_Date, Interval 365 Day) as Due_Date

From processes_active p

left JOIN processes_validations v
on p.Process_ID = (select v.validation_process_id
                   from processes_validations
                   order by validation_date desc
                   limit 1)

Having Month(Due_Date) = Month(Now()) and Year(Due_Date) = Year(Now())

Any help would be thoroughly appreciated! I'm probably pretty close just can't sort that final section!

Thanks

Your actual query is wrong, the subquery will return the very latest record in your validation table, instead of returning the latest per process id.

You should decompose to get what you need.

1) compute the latest validation for each process in the validation table:

    SELECT validation_process_id, MAX(validation_date) AS maxdate
    FROM processes_validations
    GROUP BY validation_process_id

2) For each process in the process table, get the latest validation, and compute the next validation date (use interval 1 YEAR and not 365 DAY... think leap years)

SELECT p.Process_ID, p.Process_Name, v.maxdate,
       Date_Add(v.maxdate, Interval 1 year) as Due_Date
FROM processes_active p
LEFT JOIN
    (
        SELECT validation_process_id, MAX(validation_date) AS maxdate
        FROM processes_validations
        GROUP BY validation_process_id
    )
    ON p.Process_ID = v.validation_process_id

3) Filter to keep only the due_date this month. This can be done with a WHERE on query 2, I just make a nested query for your understanding

SELECT * FROM 
(
    SELECT p.Process_ID, p.Process_Name, v.maxdate,
           Date_Add(v.maxdate, Interval 1 year) as Due_Date
    FROM processes_active p
    LEFT JOIN
        (
            SELECT validation_process_id, MAX(validation_date) AS maxdate
            FROM processes_validations
            GROUP BY validation_process_id
        )
        ON p.Process_ID = v.validation_process_id
) T
WHERE Month(Due_Date) = Month(Now()) and Year(Due_Date) = Year(Now())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM