调试 SQL 查询结果中的重复数据

当您的查询返回包含重复行或列的数据时该怎么办。

使用 Metabase 学习 SQL

免费下载 Metabase,或注册 Metabase Cloud 免费试用

您的数据在哪里重复?

重复行

开始之前,请确保您了解源表或嵌套查询的模式

  1. 您是否缺少 GROUP BY 子句?
  2. 检查您的源表或嵌套查询是否包含重复行。您需要对每个包含重复行的表或查询结果重复步骤 3 和 4。

    -- If the row_count is greater than 1,
    -- you have duplicated rows in your results.
    
     SELECT
         < your_columns >,
         COUNT(*) AS row_count
     FROM
         < your_table_or_upstream_query >
     GROUP BY
         < your_columns >
     ORDER BY
         row_count DESC;
    
  3. 查看下面的表格,了解联接类型如何与表关系交互。
  4. 更改联接类型或减少表关系.

解释

当上游系统或 ETL 作业中的数据刷新时,行可能会意外重复。

有些表格一眼看上去有重复行。这在跟踪状态变化的表格中很常见(例如,每次状态变化都会添加一行订单状态表)。状态表可能包含除行时间戳外看起来完全相同的行。如果您的表格包含大量列,可能很难检测到,因此请务必执行上述步骤 2,或者如果您不确定,请咨询您的数据库管理员。

如果您编写联接时假设是一对一关系而表格实际上具有一对多多对多关系,那么“多”表中每次匹配都会产生重复行。

进一步阅读

联接类型和表关系

此表总结了联接类型如何与表关系交互,以便在找到匹配行时产生重复项。

A 与 B 是一对一关系 A 与 B 是一对多关系 A 与 B 是多对多关系  
A INNER JOIN B 无重复行。 无重复行。 来自 A 或 B 的重复行。
A LEFT JOIN B 无重复行。 来自表 B 的可能重复项。 来自 A 或 B 的重复行。
B LEFT JOIN A 无重复行。 来自表 B 的可能重复项。 来自 A 或 B 的重复行。
A OUTER JOIN B 无重复行。 来自表 B 的可能重复项。 来自 A 或 B 的重复行。
A FULL JOIN B 无重复行。 来自表 B 的重复行。 来自 A 或 B 的重复行。

如何减少表关系

如果由于您假设是一对一关系而您的表实际上是一对多多对多关系导致重复行,您可以使用以下方法删除重复项:

  • 对于一对多关系,使用 INNER JOIN
  • 对于一对多或多对多关系,使用带聚合函数的 CTE

例如

-- Assume table_a is a one-to-many with table_b.

-- The query below will duplicate rows from table_b
-- for every matching row in table_a.

SELECT
    < your_columns >
FROM
    table_a
    LEFT JOIN table_b ON key_a = key_b;

选项 1:对一对多关系使用 INNER JOIN

-- The query below will get one row from table_b
-- for every matching row in table_a.

SELECT
    < your_columns >
FROM
    table_a
    INNER JOIN table_b ON key_a = key_b;

选项 2:使用 CTE 减少表关系

-- The query below will get aggregated values from table_b
-- for every matching row in table_a.

WITH table_b_reduced AS (
    SELECT
        AGGREGATE_FUNCTION (< your_columns >)
    FROM
        table_b_reduced
    GROUP BY
        < your_columns >
)
SELECT
    < your_columns >
FROM
    table_a
    JOIN table_b_reduced ON key_a = key_b_reduced;

重复列

  1. 如果您正在联接数据,请检查您的 SELECT 语句是否同时包含主键外键列。
  2. 通过遵循调试 SQL 逻辑下的步骤,检查您的列是否在源头重复。
  3. 了解更多关于意外查询结果的常见原因

您有其他问题吗?

您还卡住了吗?

搜索或询问  Metabase 社区

下一步:调试 SQL 查询结果中的缺失数据

当您的查询返回缺少行或列的数据时该怎么办。

下一篇文章
© . All rights reserved.