2

次のクエリに問題があります。

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 メールの作成」という要素には、2 時間のデザイナーと 2 時間の開発者がいる場合があります。次に、それぞれの時間単価に基づいてコストが計算されます。役割。

問題は、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 に「最も近い」ロールの 1 つのレートを取得したいと考えています。したがって、役割と client_company が設定された (そして client_company が Job のものと一致する) Rate レコードがあれば、それが必要です。それ以外の場合は、client_company が NULL のものにフォールバックします。

参加しようとする私の試みは明らかに間違っています。

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

client_company に一致するか、NULL の client_company を持つすべてのレコードが返されます。

最も一致するフィールドを持つものを取得するにはどうすればよいですか?

ありがとう :)

4

1 に答える 1

2

あなたが試すことができるのは、あなたが絶対に一致させたい1つのパラメータに対して基本的にすべての一致率を取得する1つのクエリを持つことです-roleあなたの場合のようです。

次に、次のようなことを行うことができます。

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

これにより、可能な最大レート、つまり、最も一致するフィールドがある場合に適用可能なレートが得られます。

于 2012-10-12T07:28:23.880 に答える