条件表达式 (CASE)
示例图
以下图用于下面的示例
要重新创建该图,请在空的 Neo4j 数据库上运行以下查询
CREATE
(alice:Person {name:'Alice', age: 38, eyes: 'brown'}),
(bob:Person {name: 'Bob', age: 25, eyes: 'blue'}),
(charlie:Person {name: 'Charlie', age: 53, eyes: 'green'}),
(daniel:Person {name: 'Daniel', eyes: 'brown'}),
(eskil:Person {name: 'Eskil', age: 41, eyes: 'blue'}),
(alice)-[:KNOWS]->(bob),
(alice)-[:KNOWS]->(charlie),
(bob)-[:KNOWS]->(daniel),
(charlie)-[:KNOWS]->(daniel),
(bob)-[:MARRIED]->(eskil)
简单 CASE
简单 CASE
形式用于将单个表达式与多个值进行比较,类似于编程语言的 switch
结构。通过 WHEN
运算符评估表达式,直到找到匹配项。如果未找到匹配项,则返回 ELSE
运算符中的表达式。如果没有 ELSE
情况且未找到匹配项,则将返回 null
。
扩展简单 CASE
扩展简单 CASE
形式允许显式指定比较运算符。简单 CASE
使用隐式等于 (=
) 比较器。
支持的比较器是
-
常规比较运算符:
=
,<>
,<
,>
,<=
,>=
-
IS NULL
运算符:IS [NOT] NULL
-
类型谓词表达式:
IS [NOT] TYPED <TYPE>
(注意,形式IS [NOT] :: <TYPE>
不被接受) -
规范化谓词表达式:
IS [NOT] NORMALIZED
-
字符串比较运算符:
STARTS WITH
,ENDS WITH
,=~
(正则表达式匹配)
语法
CASE test
WHEN [comparisonOperator] value [, [comparisonOperator] value ]* THEN result
[WHEN ...]
[ELSE default]
END
参数
名称 | 描述 |
---|---|
|
一个表达式。 |
|
支持的比较运算符之一。 |
|
一个表达式,其结果使用给定的比较运算符与 |
|
如果 |
|
如果没有任何值与测试表达式匹配,则要返回的表达式。 |
示例
MATCH (n:Person)
RETURN n.name,
CASE n.age
WHEN IS NULL, IS NOT TYPED INTEGER | FLOAT THEN "Unknown"
WHEN = 0, = 1, = 2 THEN "Baby"
WHEN <= 13 THEN "Child"
WHEN < 20 THEN "Teenager"
WHEN < 30 THEN "Young Adult"
WHEN > 1000 THEN "Immortal"
ELSE "Adult"
END AS result
n.name | result |
---|---|
|
|
|
|
|
|
|
|
|
|
行数:5 |
通用 CASE
通用 CASE
表达式支持多个条件语句,类似于编程语言的 if-elseif-else
结构。每个行按顺序评估,直到找到一个 true
值。如果未找到匹配项,则返回 ELSE
运算符中的表达式。如果没有 ELSE
情况且未找到匹配项,则将返回 null
。
带有 null
值的 CASE
在使用 null
值时,你可能被迫使用通用 CASE
形式。以下两个示例使用 Daniel
节点的 age
属性(该属性的 age
值为 null
)来阐明差异。
CASE
MATCH (n:Person)
RETURN n.name,
CASE n.age (1)
WHEN null THEN -1 (2)
ELSE n.age - 10 (3)
END AS age_10_years_ago
1 | n.age 是正在评估的表达式。请注意,节点 Daniel 的 age 值为 null 。 |
2 | 此分支被跳过,因为 null 不等于任何其他值,包括 null 本身。 |
3 | 执行进入 ELSE 分支,它输出 null ,因为 n.age - 10 等于 null 。 |
n.name | age_10_years_ago |
---|---|
|
|
|
|
|
|
|
|
|
|
行数:5 |
CASE
MATCH (n:Person)
RETURN n.name,
CASE (1)
WHEN n.age IS NULL THEN -1 (2)
ELSE n.age - 10
END AS age_10_years_ago
1 | 如果没有在 CASE 后提供表达式,它将以通用形式运行,支持每个分支中的谓词表达式。 |
2 | 此谓词表达式对于节点 Daniel 计算为 true ,因此返回此分支的结果。 |
n.name | age_10_years_ago |
---|---|
|
|
|
|
|
|
|
|
|
|
行数:5 |
有关 null
的更多信息,请参阅 使用 null
。
CASE
表达式和后续子句
CASE
表达式的结果可用于设置节点或关系上的属性。
MATCH (n:Person)
WITH n,
CASE n.eyes
WHEN 'blue' THEN 1
WHEN 'brown' THEN 2
ELSE 3
END AS colorCode
SET n.colorCode = colorCode
RETURN n.name, n.colorCode
n.name | n.colorCode |
---|---|
|
|
|
|
|
|
|
|
|
|
行数:5 |
有关使用 SET
子句的更多信息,请参阅 SET。
其他注意事项
CASE
结果分支在执行之前会进行静态检查。这意味着,如果一个分支在语义上不正确,它仍然会抛出一个异常,即使该分支可能在运行时永远不会被执行。
在以下示例中,date
静态地知道是一个 STRING
值,因此如果将其视为 DATE
值,则会失败。
WITH "2024-08-05" AS date, "string" AS type
RETURN CASE type
WHEN "string" THEN datetime(date)
WHEN "date" THEN datetime({year: date.year, month: date.month, day: date.day})
ELSE datetime(date)
END AS dateTime
Type mismatch: expected Map, Node, Relationship, Point, Duration, Date, Time, LocalTime, LocalDateTime or DateTime but was String (line 4, column 38 (offset: 136))
" WHEN 'date' THEN datetime({year: date.year, month: date.month, day: date.day})"
^