簡體   English   中英

通過MAX挑戰LEFT OUTER JOIN查詢分組

[英]Challenging LEFT OUTER JOIN query grouping by MAX

我有以下兩個表:

BillingMatrixDefinition
    - id
    - amount

BillingMatrix
   - definition (FK to table above)
   - service_id (FK)
   - provider_id (FK)
   - amount (Decimal)

我需要獲取具有我指定的service_idprovider_id所有BillingMatrixDefinitions。 這是我當前擁有的SQL查詢:

select def.id, service_id, provider_id, 
 (case when matrix.amount is not null then matrix.amount else def.amount end) amount
    from billing_billingdefinition def 
        left outer join billing_billingmatrix matrix
        on matrix.definition_id=def.id 
    where (service_id = 25 or service_id is null)
      and (provider_id = 24 or provider_id is null)

這給了我以下結果:

id      service_id  provider_id   amount
1       25          24            200.00
1       NULL        24            300.00
2       NULL        24            800.00
3       NULL        NULL          750.00
5       NULL        NULL          450.00
6       NULL        NULL          750.00

但是,我需要得到每個ID的結算量,所以我只能得到一個項目/金額為每個id 在這種情況下,我想獲取service_id=24的項目,如果不存在,請在service_id=NULL

正確的查詢應該給我以下結果:

id      service_id  provider_id   amount
1       25          24            200.00
2       NULL        24            800.00
3       NULL        NULL          750.00
5       NULL        NULL          450.00
6       NULL        NULL          750.00

請注意,現在沒有1的重復條目,我使用已輸入service_id的行項目(如果存在,則使用該項目,否則使用NULL)。 什么是正確的查詢來做到這一點?

另一種方式:

SELECT 
    def.id                                              AS id, 
    COALESCE(matrix.service_id, matrix2.service_id)     AS service_id, 
    COALESCE(matrix.provider_id, matrix2.provider_id)   AS provider_id, 
    COALESCE(matrix.amount, matrix2.amount, def.amount) AS amount 
FROM 
        billing_billingdefinition AS def 
    LEFT JOIN 
        billing_billingmatrix AS matrix 
            ON  matrix.definition_id = def.id 
            AND matrix.service_id = 25 
            AND matrix.provider_id = 24 
    LEFT JOIN 
        billing_billingmatrix AS matrix2
            ON  matrix2.definition_id = def.id 
            AND matrix2.service_id IS NULL
            AND matrix2.provider_id = 24  ; 

嘗試以下方法(利用臨時表):

CREATE TEMPORARY TABLE Results
select def.id, service_id, provider_id, 
 (case when matrix.amount is not null then matrix.amount else def.amount end) amount
    from billing_billingdefinition def 
        left outer join billing_billingmatrix matrix
        on matrix.definition_id=def.id 
    where (service_id = 25 or service_id is null)
      and (provider_id = 24 or provider_id is null);

SELECT * 
FROM Results r1
WHERE IFNULL(r1.service_id, 0) = 
      ( SELECT MAX(IFNULL(r2.service_id, 0)) 
        FROM Results r2 
        WHERE r2.id = r1.id
      );

SQL Fiddle僅用於第二部分(使用已經創建的Results表)

您需要使用max()來匯總金額max()當然還要添加group-by子句),以便在存在一個非null值的情況下獲得該值:

select
    def.id, service_id, provider_id, 
    max(case when matrix.amount is not null then matrix.amount else def.amount end) amount
    from billing_billingdefinition def 
    left outer join billing_billingmatrix matrix
        on matrix.definition_id=def.id 
    where (service_id = 25 or service_id is null)
    and (provider_id = 24 or provider_id is null)
   group by def.id, service_id, provider_id

這樣的事情也可能起作用。

select def.id, service_id, provider_id, IFNULL(matrix.amount,def.amount) amount
    from billing_billingdefinition def 
    left outer join (select definition_id, max(service_id) as maxsid from billing_billingmatrix matrix group by definition_id) as t1
        on def.id = t1.definition_id 
left outer join billing_billingmatrix matrix
    on matrix.definition_id=def.id and maxsid <=> service_id

嘗試這個:

SELECT BMD.id, BM.service_id, BM.provider_id, IFNULL(BM.amount, BMD.amount) AS amount 
FROM BillingMatrixDefinition BMD
LEFT JOIN BillingMatrix BM ON BMD.id = BM.definition_id AND (BM.service_id = 25 OR BM.provider_id = 24)
GROUP BY BMD.id;

我相信PM 771的答案在這里也適用,但是我決定在OUTER JOIN表中使用子選擇,以在加入之前對結果進行預過濾。

這是為此工作的最終SQL:

SELECT *,
       (CASE WHEN matrix.amount IS NOT NULL THEN matrix.amount ELSE def.amount END) calculated_amount,
    FROM billing_billingdefinition def
    LEFT OUTER JOIN
       (SELECT t.* FROM (
        select * from billing_billingmatrix 
        where (provider_id=25 
        or provider_id is null) 
        and (service_id=24 or service_id is null)
        ORDER BY service_id DESC
          ) t GROUP BY t.definition_id) matrix
            ON matrix.definition_id=def.id

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM