调试 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
子句。 - 对于保存的问题或模型,请从变量面板转到基础 Metabase 问题,或通过将 ID 号粘贴到搜索栏中。使用查询构建器添加行限制,或在 SQL 编辑器中添加
LIMIT
子句。
- 对于子查询或 CTE,单独运行每个
- 比较样本之间的列名和值以检查外键。例如
- 在 Metabase 示例数据库中,
Products
表有一个ID
列,而Orders
表有一个Product ID
列。 ID
和Product ID
都包含整数值,并且这些值中的许多都出现在这两个列中。
- 在 Metabase 示例数据库中,
- 比较样本之间的行以检查表关系。例如
Products
表在ID
列中具有唯一值。Orders
表有多个具有相同Product ID
的行。- 从
Products
到Orders
的表关系是一对多(假设外键关系有效)。
- 如果您正在使用模型,您可以通过将鼠标悬停在列名上来查找明确定义的元数据。
- 如果您是基于他人的工作进行构建,请咨询查询、已保存问题或模型的原始创建者。
解释
模式描述了表中的列、这些列的数据类型以及不同表之间列的关系。此元数据通常由管理数据的团队为存储在数据库中的表明确定义。
由于嵌套查询的结果仅临时存储,因此关于结果的元数据未在任何地方定义或存储。上述步骤将帮助您手动检查查询结果。
一旦您拥有嵌套查询的模式,您就可以按照调试步骤进行操作。
延伸阅读
您有其他问题吗?
您还卡住了吗?
搜索或咨询 Metabase 社区。