一种方法将涉及相关子查询:
SELECT   e.id AS element_id,
         h.role,
         SUM(h.hours_budgeted) AS total_hours_budgeted,
         r.hourly_rate,
         e.pm_amount,
         e.revenue AS fixed_revenue,
         e.revenue_extra,
         SUM(h.hours_budgeted) * r.hourly_rate AS element_subtotal
FROM     job                    j
    JOIN job_element            e ON e.job     = j.id
    JOIN job_element_role_hours h ON h.element = e.id
    JOIN rate                   r ON r.id      = (
           SELECT   id
           FROM     rate
           WHERE    rate.role = h.role
                AND IFNULL(rate.client_company = j.client_company, TRUE)
                AND IFNULL(rate.client_group   = j.client_group  , TRUE)
                AND IFNULL(rate.client_contact = j.client_contact, TRUE)
           ORDER BY rate.client_company DESC,
                    rate.client_group   DESC,
                    rate.client_contact DESC,
                    rate.date_from      DESC
           LIMIT    1
         )
WHERE    j.id = 1
GROUP BY e.id, h.role
在sqlfiddle上查看。
但是,相关子查询效率低下并且可能很慢。正如手册所说:
  将查询重写为连接可能会提高性能。
为此,必须获得分组最大值:
SELECT   e.id AS element_id,
         h.role,
         SUM(h.hours_budgeted) AS total_hours_budgeted,
         r.hourly_rate,
         e.pm_amount,
         e.revenue AS fixed_revenue,
         e.revenue_extra,
         SUM(h.hours_budgeted) * r.hourly_rate AS element_subtotal
FROM     job                    j
    JOIN job_element            e ON e.job     = j.id
    JOIN job_element_role_hours h ON h.element = e.id
    JOIN rate                   r ON r.role    = h.role
           AND IFNULL(r.client_company = j.client_company, TRUE)
           AND IFNULL(r.client_group   = j.client_group  , TRUE)
           AND IFNULL(r.client_contact = j.client_contact, TRUE)
    JOIN (
      SELECT   j.client_company, j.client_group, j.client_contact, r.role,
               MAX(
                 IF(r.client_company <=> j.client_company, 1<<34, 0)
               | IF(r.client_group   <=> j.client_group  , 1<<33, 0)
               | IF(r.client_contact <=> j.client_contact, 1<<32, 0)
               | UNIX_TIMESTAMP(r.date_from)
               ) AS relevance
      FROM     rate r JOIN job j ON
                     IFNULL(r.client_company = j.client_company, TRUE)
                 AND IFNULL(r.client_group   = j.client_group  , TRUE)
                 AND IFNULL(r.client_contact = j.client_contact, TRUE)
      GROUP BY j.client_company, j.client_group, j.client_contact, r.role
    ) t     ON t.role = r.role
           AND t.client_company = j.client_company
           AND t.client_group   = j.client_group
           AND t.client_contact = j.client_contact
           AND t.relevance  = IF(r.client_company <=> j.client_company, 1<<34, 0)
                            | IF(r.client_group   <=> j.client_group  , 1<<33, 0)
                            | IF(r.client_contact <=> j.client_contact, 1<<32, 0)
                            | UNIX_TIMESTAMP(r.date_from)
WHERE    j.id = 1
GROUP BY e.id, h.role
在sqlfiddle上查看。
在这里,我通过计算相关性分数找到了与您的尝试类似的分组最大值。然而,我通过一些位旋转,其中 2 34表示是否存在匹配client_company,2 33和client_group2 32表示速率,client_contact32 个最低位表示速率date_from- 然后取最大相关分数将产生分数最好的匹配,并再次加入rate表使人们能够获得hourly_rate所需的。
甚至可以进一步改进这一点,以避免计算相关性分数,方法是嵌套以按顺序在每列上找到分组最大值;但是,除非您遇到无法以任何其他方式解决的性能问题,否则可能不值得走这条路。您可以在我对另一个问题的回答中看到该技术。