LEFT OUTER JOIN cant group列并返回重复项

时间:2016-08-26 23:40:42

标签: mysql sql left-join grouping

我简化了我的问题并整理了这个例子。对不起,感到困惑。

我有两张桌子

kpi_index和audit_results

kpi_index包含8个唯一的sor_code,用于子类别'C1' audit_results包含带审计的记录 kpi_index通过INDEX字段连接到sor_code kpi_index字段

我需要结果显示'全部'8个sor_codes以及每个sor_code的审核次数,符合的审核次数和百分比次数,但是,如果没有任何sor_code的结果,则显示NULL或'0' sor_code。

我想出了这个查询,但由于某些原因,如果找到了结果,我会得到重复的sor_codes,即audit_results中的值,例如从audit_results表返回C1.TAM和C1.TOM值,因此我不需要从匹配sor_code / record的kpi_index中显示null。

我的目标是显示kpi_index中可用的所有sor_codes,并填充在连接的audit_results表中找到匹配的sor_codes,并将匹配的空行替换为填充的“audited / complied / percentage”值 - 应该没有如果在audit_results中找到匹配的sor_code,则复制带有空值的sor_code。

由于

sor_code    Spec. Code  audits  complied    percentage  contractor
C1.SNM  C1  0   null    null    null
C1.SSM  C1  0   null    null    null
C1.TAM  C1  0   null    null    null
C1.TAM  C1  186 151 81% South
C1.TIM  C1  0   null    null    null
C1.TNM  C1  0   null    null    null
C1.TOM  C1  0   null    null    null
C1.TOM  C1  41  40  98% South

SELECT DISTINCT
      kpi_index.sor_code,
      kpi_index.`Spec. Code`,
      COUNT(audit_results.compliance) AS audits,
      SUM(audit_results.compliance) AS complied,
      CONCAT(ROUND(SUM(audit_results.compliance) / COUNT(kpi_index.sor_code) * 100, 0), '%') AS percentage,
      audit_results.contractor
    FROM kpi_index
      LEFT OUTER JOIN audit_results
        ON kpi_index.`INDEX` = audit_results.kpi_index
    WHERE audit_results.contractor = 'South'
    OR auit_results.contractor IS NULL
    GROUP BY kpi_index.sor_code,
             audit_results.contractor
    HAVING kpi_index.`Spec. Code` = 'C1'
    ORDER BY kpi_index.sor_code

1 个答案:

答案 0 :(得分:0)

SELECT
    kpi_index.sor_code,
    min(kpi_index.`Spec. Code`) AS spec_code,
    COUNT(audit_results.compliance) AS audits,
    SUM(audit_results.compliance) AS complied,
    CONCAT(ROUND(
        SUM(audit_results.compliance) * 100.00
            / COUNT(kpi_index.sor_code),
        0), '%') AS percentage,
    MIN(audit_results.contractor) AS contractor
FROM
    kpi_index
    LEFT OUTER JOIN audit_results
        ON kpi_index.`INDEX` = audit_results.kpi_index
           AND audit_results.contractor = 'South'
WHERE kpi_index.`Spec. Code` = 'C1'
GROUP BY kpi_index.sor_code
ORDER BY kpi_index.sor_code
  1. DISTINCT没有必要。当您包含所有GROUP BY列时,结果已经不同。

  2. 您遇到的主要问题是尝试过滤 您只能加入contractor = 'South'行。当你使用 在外部联接中,您必须小心WHERE子句条件 因为首先在逻辑上完成连接,然后再应用条件。当您的加入仅与不同名称的承包商匹配时,您的所有行都不会与is null= 'South'测试匹配。

  3. HAVING中的条件确实属于WHERE 条款。即使MySQL,它实际上也没有严格意义 似乎接受了它。

  4. 我删除了contractor更喜欢使用的额外分组 而是MIN()列表中的SELECT。最终它应该是 如果我假设contractor不可为空,那就多余了 正确的。