调试 SQL 查询逻辑
当查询返回看起来错误的数据时该怎么办。
数据组合很快就会变得复杂(这可能就是您耐心编写 SQL 而不是使用友好的查询构建器的原因)。本调试指南解释了当您的查询返回意外结果时您可以做什么。
调试步骤
- 获取查询中使用的数据源的模式。
- 如果您正在使用数据库中的表,请从数据参考中获取模式。
- 如果您正在使用嵌套查询(例如子查询、CTE、已保存的问题或模型),则需要单独运行每个嵌套查询并手动检查结果。
- 我不知道我是否正在使用嵌套查询.
- 检查您的表或嵌套查询的外键。
- 是否有多个可能的外键?
- 外键是否已重命名或移动到另一个模式?
- 如果您不确定,请咨询维护模式的人员。
- 检查常见的 SQL 逻辑问题。
查询结果意外的常见原因
SQL 逻辑描述了您的查询如何组合来自不同表或数据源的数据(包括临时表,例如其他查询的结果)。最常见的数据组合方式是连接和嵌套查询。
即使您的 SQL 逻辑过去有效,也可能在以下情况下中断
- 表或数据源已更改。
- 嵌套查询已更改(如果您在已保存的问题或模型之上构建)。
- 您的嵌套查询未按预期计算(如果您是从头开始编写它们)。
- 您的数据包括边缘情况,例如空值或
NULL
值。
大多数情况下,这些更改是由收集数据的系统或管理数据库和 BI 工具的可爱人员在上游引入的。
团队很难预测此类更改的连锁反应。修复 SQL 逻辑不仅是响应更改,而且是更新您的方法以更好地防范未来的更新。
如果您收到红色错误消息,其中提到 SQL 子句或表和列名,则您很可能遇到 SQL 语法问题。请改为转到调试 SQL 语法。
常见的 SQL 逻辑问题
聚合结果(计数、总和等)是错误的
- 如果您的聚合是
- 检查您的源表或查询是否有过滤器。
- 您如何在聚合中处理空行或
NULL
行? - 您如何处理无效、已取消或过期的记录?向您的 Metabase 管理员或数据团队询问您可能不知道的业务逻辑。
- 您如何在聚合中处理空行或
- 如果您正在使用
COUNT_DISTINCT
,请检查它是否与其他聚合函数交互。- 例如,在
COUNT_DISTINCT
之上应用SUM
可能会重复计算唯一值。
- 例如,在
- 如果您正在使用时间序列数据,请检查您的时区。
- 如果您的数据按计划更新,请询问您的 Metabase 管理员您的表是否是最新的。
说明
聚合通常是您检测到由查询结果意外的常见原因之一引起的问题的第一个地方。以上步骤将帮助您捕获任何可能扭曲结果的数据边缘情况。如果您发现很多边缘情况,并且您预计会一遍又一遍地处理相同的情况,您可能希望将所有这些逻辑捆绑到一个模型中,以便可以轻松地重复使用。
有时,您可能只需要一双新的眼睛。如果您无法使用上述步骤找到根本原因,请让队友帮助您检查您的数学!
延伸阅读
如何识别嵌套查询
如果您的 SQL 包含
-
多个
SELECT
语句,您正在使用子查询。 -
WITH
子句,您正在使用 CTE(公用表表达式)。 -
在您的
FROM
或WITH
子句中看起来像{{ variable }}
的符号,您有一个SQL 变量,它引用了已保存的问题或模型。
如何获取嵌套查询的模式
- 从您的嵌套查询中获取数据样本。
- 对于子查询或 CTE,分别运行每个
SELECT
块并使用LIMIT
子句。 - 对于已保存的问题或模型,请从变量面板或通过将 ID 号粘贴到搜索栏中,转到基础 Metabase 问题。使用查询构建器添加行限制,或在 SQL 编辑器中添加
LIMIT
子句。
- 对于子查询或 CTE,分别运行每个
- 比较样本之间的列名和值,以检查外键。例如
- 在Metabase 示例数据库中,“
产品
”表有一个“ID
”列,“订单
”表有一个“产品 ID
”列。 - “
ID
”和“产品 ID
”都包含整数值,并且其中许多值都显示在两列中。
- 在Metabase 示例数据库中,“
- 比较样本之间的行,以检查表关系。例如
- “
产品
”表的“ID
”列中具有唯一值。 - “
订单
”表有多行具有相同的“产品 ID
”。 - 从“
产品
”到“订单
”的表关系是一对多(假设外键关系有效)。
- “
- 如果您正在使用模型,则可以通过将鼠标悬停在列名上来查找显式定义的元数据。
- 如果您是基于其他人的工作构建的,请咨询查询、已保存的问题或模型的原始创建者。
说明
模式描述了表中的列、这些列的数据类型以及不同表之间列的关系。此元数据通常由管理数据的用户为存储在数据库中的表显式定义。
由于嵌套查询的结果仅临时存储,因此有关结果的元数据未在任何地方定义或存储。以上步骤将帮助您手动检查查询结果。
获得嵌套查询的模式后,您可以按照调试步骤进行操作。
延伸阅读
您有其他问题吗?
您仍然遇到困难吗?
搜索或咨询Metabase 社区。
下一步:调试 SQL 查询结果中的重复数据
当您的查询返回具有重复行或列的数据时该怎么办。