加入可选的空值

时间:2012-10-03 11:51:52

标签: mysql join null

我遇到以下问题时出现问题:

SELECT 
    job.name,
    job_element.label,
    job_element_role_hours.role,
    job_element_role_hours.hours_budgeted,
    latest_rate.hourly_rate,
    ( job_element_role_hours.hours_budgeted * latest_rate.hourly_rate ) AS line_cost
FROM
    job_element
    INNER JOIN job ON job_element.job = job.id
    INNER JOIN job_element_role_hours ON job_element_role_hours.element = job_element.id
    LEFT JOIN(
        SELECT 
            rate.*
        FROM
            rate
        LEFT JOIN rate AS newest ON (
            rate.role = newest.role
            AND COALESCE(rate.client_company, 1) = COALESCE(newest.client_company, 1)
            AND COALESCE(rate.client_group, 1) = COALESCE(newest.client_group, 1)
            AND COALESCE(rate.client_contact, 1) = COALESCE(newest.client_contact, 1)
            AND newest.date_from > rate.date_from
        )
        WHERE newest.id IS NULL
    ) AS latest_rate ON (
        latest_rate.role = job_element_role_hours.role
        AND (
            COALESCE(latest_rate.client_company, 1) = COALESCE(job.client_company, 1)
            OR latest_rate.client_company IS NULL
        )
        AND (
            COALESCE(latest_rate.client_group, 1) = COALESCE(job.client_group, 1)
            OR latest_rate.client_group IS NULL
        )
        AND (
            COALESCE(latest_rate.client_contact, 1) = COALESCE(job.client_contact, 1)
            OR latest_rate.client_contact IS NULL
        )

    )
WHERE job.id = 4

所以...此查询获取作业的元素列表。每个元素按“角色时间”细分 - 例如,一个名为“构建HTML电子邮件”的元素,可能有两个小时的Designer,两个小时的开发人员 - 然后根据每个小时的每小时费率计算成本作用。

问题在于我将 latest_rate 子查询加入主查询。这是我的费率表:

'CREATE TABLE `rate` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `client_company` int(11) DEFAULT NULL,
  `client_group` int(11) DEFAULT NULL,
  `client_contact` int(11) DEFAULT NULL,
  `role` int(11) DEFAULT NULL,
  `date_from` datetime DEFAULT NULL,
  `hourly_rate` decimal(18,2) DEFAULT NULL,
  `last_edited_by` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

角色可能有多种速率:设置角色的“全局”速率,但client_company,client_group和client_contact字段为NULL;特定于公司的速率,其中设置了角色和client_company但其他所有内容都为NULL,以及特定于客户端的速率,其中设置了角色client_company和client_contact但client_group为NULL。

我想获得“最接近”匹配为作业设置的client_company,client_group和client_contact的角色的一个费率。因此,如果设置了角色和client_company的Rate记录(并且client_company与Job的匹配),我想要那个。否则,我将回到NULL client_company。

我加入的尝试显然是错误的:

AND (
     COALESCE(latest_rate.client_company, 1) = COALESCE(job.client_company, 1)
     OR latest_rate.client_company IS NULL
)

它将返回与client_company匹配的所有记录,或者返回NULL client_company。

如何才能获得具有最匹配字段的那个?

谢谢:)

1 个答案:

答案 0 :(得分:2)

你可以尝试的是一个查询基本上可以获得一个你绝对想要匹配的参数的所有匹配率 - 在你的情况下似乎是role

然后你可以这样做:

MAX(
    CASE WHEN <conditions 1> THEN <calculation 1> END,
    CASE WHEN <conditions 2> THEN <calculation 2> END,
    ...
    )

这将为您提供可能的最大费率,即,如果您拥有最匹配的字段,则适用的费率。