Case

case(别名 if)检查值是否与条件列表匹配,并根据满足的第一个条件返回一些输出。ifcase 的工作方式完全相同。

您可以选择告知 case,如果没有满足任何条件,则返回默认输出。如果您未设置默认输出,则 case 将在检查完所有条件后返回 nullnull 值在 Metabase 中显示为空白值)。

在您需要以下情况时,请使用 case 表达式

语法
case(条件 1, 输出 1, 条件 2, 输出 2, ..., 默认输出)
返回满足的第一个条件的输出。
示例
case(isempty("glass half full"), "空杯子", isnull("glass half full"), "缺少杯子", "半杯水")
“半杯水”

为频率表或直方图分桶数据

金额
6 0-9
18 10-19
31 30-39
57 50+

其中 是带有表达式的自定义列

case([Amount] >= 0  AND [Amount] <=  9,  "0-9",
     [Amount] >= 10 AND [Amount] <= 19,  "10-19",
     [Amount] >= 20 AND [Amount] <= 29,  "20-29",
     [Amount] >= 30 AND [Amount] <= 39,  "30-39",
     [Amount] >= 40 AND [Amount] <= 49,  "40-49", "50+")

基于多列条件标记行

目击 ID 有翅膀 有脸 目击类型
1
2 飞机
3 超人
4 未知

其中 目击类型 是带有表达式的自定义列

case([Has Wings] = TRUE  AND [Has Face] = TRUE,  "Bird",
     [Has Wings] = TRUE  AND [Has Face] = FALSE, "Plane",
     [Has Wings] = FALSE AND [Has Face] = TRUE,  "Superman", "Unknown")

您可以使用包含“标签”的列来

基于多列条件聚合数据

您可以将 case聚合函数结合使用,以仅聚合满足您条件的行。

例如,如果我们想计算每个订单日期的唯一订单数,但仅限于状态为“已发货”的订单

订单 ID 订单日期 状态
1 2022-04-01 已付款
1 2022-04-03 已发货
2 2022-05-12 已付款
2 2022-05-12 已取消
  1. 创建自定义表达式 distinct(case([状态] = "已发货", [订单 ID])) 并将其命名为“已发货订单总数”。
  2. 选择 订单日期 作为分组列。
  3. 点击 可视化 以返回结果
订单日期 已发货订单总数
2022-04-01 1
2022-05-01 0

接受的数据类型

数据类型 适用于 case
字符串
数字
时间戳
布尔值
JSON

限制

所有输出必须具有相同的数据类型。

避免:

case(condition1, "string", condition2, TRUE, condition3, 1)

推荐:

case(condition1, "string", condition2, "TRUE", condition3, "1")

本节介绍可以与 Metabase case 表达式互换使用的函数和公式,并附注如何为您的用例选择最佳选项。

Metabase 表达式

其他工具

Coalesce

使用来自Coalesce:合并值示例的表格

备注 评论 coalesce([备注], [评论], "无备注或评论。")
我有备注。 我有评论。 我有备注。
  我有评论。 我有评论。
我有备注。   我有备注。
    无备注或评论。

Metabase coalesce 表达式

coalesce([Notes], [Comments] "No notes or comments.")

等效于 case 表达式

case(ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = FALSE, [Notes],
     ISBLANK([Notes]) = TRUE  AND ISBLANK([Comments]) = False, [Comments],
     ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = TRUE,  [Notes],
     ISBLANK([Notes]) = TRUE  AND ISBLANK([Comments]) = TRUE,  "No notes or comments")

如果您不介意在两列都不为空白时取第一个值,则 coalesce 更易于编写。如果您想为此情况定义特定输出(例如,“我既有备注_又_有评论”),请使用 case

Countif

使用来自聚合数据示例的表格

订单 ID 订单日期 状态
1 2022-04-01 已付款
1 2022-04-03 已发货
2 2022-05-12 已付款
2 2022-05-12 已取消

Metabase countif 表达式

countif(case([Status] = "Shipped"))

等效于 case 表达式

count(case([Status] = "Shipped", [Row ID]))

当您计算表中满足您条件的所有行时,countif 等效于 case。如果您想计算满足您条件的唯一行,则不等效

Sumif

使用来自聚合数据示例的扩展版本表格

行 ID 订单 ID 订单日期 状态 金额
1 1 2022-04-01 已付款 $20
2 1 2022-04-03 已发货 $20
3 2 2022-05-12 已付款 $80
4 2 2022-05-12 已取消 $80

Metabase sumif 表达式

sumif([Amount], [Status] = "Shipped")

等效于 case 表达式

sum(case([Status] = "Shipped", [Amount]))

当您为单个条件对单列求和时,sumif 等效于 case

如果您想在第二个单独的条件下对第二列求和,则应使用 case。例如,如果您想在 状态 = “已发货”时对 金额 列求和,并在 状态 = “已退款”时对另一个(假设的)列(如 退款金额)求和。

SQL

在大多数情况下(除非您使用的是 NoSQL 数据库),从笔记本编辑器创建的问题会转换为针对您的数据库或数据仓库运行的 SQL 查询。Metabase case 表达式会转换为 SQL CASE WHEN 语句。

使用来自标记行示例的表格

目击 ID 有翅膀 有脸 目击类型
1
2 飞机
3 超人
4 未知

SQL CASE WHEN 语句

SELECT
    CASE WHEN "Has Wings" = TRUE  AND "Has Face" = TRUE  THEN "Bird"
         WHEN "Has Wings" = TRUE  AND "Has Face" = FALSE THEN "Plane"
         WHEN "Has Wings" = FALSE AND "Has Face" = TRUE  THEN "Superman"
         ELSE "Unknown" END
FROM mystery_sightings

等效于用于 目击类型case 表达式

case([Has Wings] = TRUE  AND [Has Face] = TRUE,  "Bird",
     [Has Wings] = TRUE  AND [Has Face] = FALSE, "Plane",
     [Has Wings] = FALSE AND [Has Face] = TRUE,  "Superman", "Unknown")

例如,这个用于对条形图进行排序的 SQL 技巧可以使用 Metabase case 表达式代替编写。

电子表格

使用来自标记行示例的表格

目击 ID 有翅膀 有脸 目击类型
1
2 飞机
3 超人
4 未知

电子表格公式

=IF(AND(B2 = TRUE, C2 = TRUE), "Bird",
    IF(AND(B2 = TRUE, C2 = FALSE), "Plane",
       IF(AND(B2 = FALSE, C2 = TRUE), "Superman", "Unknown")
      )
    )

等效于用于 目击类型case 表达式

case([Has Wings] = TRUE  AND [Has Face] = TRUE,  "Bird",
     [Has Wings] = TRUE  AND [Has Face] = FALSE, "Plane",
     [Has Wings] = FALSE AND [Has Face] = TRUE,  "Superman", "Unknown")

Python

有很多方法可以使用 Python 实现条件逻辑。我们将介绍转换为 Metabase case 表达式有意义的方法。

使用来自标记行示例的表格(并假设它在名为 df 的数据帧中)

目击 ID 有翅膀 有脸 目击类型
1
2 飞机
3 超人
4 未知

numpy select()

conditions = [
    (df["has_wings"] == True) & (df["has_face"] == True),
    (df["has_wings"] == True) & (df["has_face"] == False),
    (df["has_wings"] == False) & (df["has_face"] == True)]

outputs = ["Bird", "Plane", "Superman"]

df["Sighting Type"] = np.select(conditions, outputs, default="Unknown")

带有 pandas apply() 的辅助函数

def Identify(df):
    if ((df["has_wings"] == True) & (df["has_face"] == True)):
        return "Bird"
    elif ((df["has_wings"] == True) & (df["has_face"] == False)):
        return "Plane"
    elif ((df["has_wings"] == False) & (df["has_face"] == True)):
        return "Superman"
    else:
        return "Unknown"

df["Sighting Type"]= df.apply(Identify, axis=1)

上述方法等效于用于 目击类型case 表达式

case([Has Wings] = TRUE  AND [Has Face] = TRUE,  "Bird",
     [Has Wings] = TRUE  AND [Has Face] = FALSE, "Plane",
     [Has Wings] = FALSE AND [Has Face] = TRUE,  "Superman", "Unknown")

进一步阅读