调试 SQL 查询结果中的重复数据
当你查询返回具有重复行或列的数据时,该怎么办。
您的数据在哪里被重复了?
重复行
在开始之前,请确保您了解源表或嵌套查询的架构。
- 您是否缺少一个
GROUP BY
子句? -
检查您的源表或嵌套查询是否有重复行。对于每个包含重复行的表或查询结果,您需要重复步骤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;
- 查看下面的表,了解您的连接类型如何与表关系交互。
- 更改连接类型或减少表关系.
说明
当上游系统或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;
重复列
- 如果您正在连接数据,请检查您的
SELECT
语句是否包括主键和外键列。 - 通过遵循调试SQL逻辑下的步骤来检查您的列是否在源处重复。
- 了解更多关于查询结果意外的常见原因。
您有不同的问题吗?
你还卡住了吗?
搜索或询问Metabase社区。
下一步:调试SQL查询结果中的缺失数据
当你的查询返回缺少行或列的数据时,该怎么做。