

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Ifelse


`ifelse` 对一组 *if*/*then* 表达式对进行计算，并返回计算结果为 true 的第一个 *if* 参数的 *then* 参数值。如果所有 *if* 参数的计算结果都不为 true，则返回 *else* 参数的值。

## 语法


```
ifelse(if-expression-1, then-expression-1 [, if-expression-n, then-expression-n ...], else-expression)
```

## Arguments


`ifelse` 需要一个或多个 *if*/*then* 表达式对，*else* 参数只需要一个表达式。

 *if-expression*   
表达式的计算结果为 true 或 false。它可以是字段名称（如 **address1**）、文本值（如 **'Unknown'**）或其他函数（如 `toString(salesAmount)`）。例如，`isNotNull(FieldName)`。  
如果您在 `if` 参数中使用了多个 AND 和 OR 运算符，请给语句加上括号以确定处理顺序。例如，以下 `if` 参数返回 2000 年 1、2 或 5 月份的记录。  

```
ifelse((month = 5 OR month < 3) AND year = 2000, 'yes', 'no')
```
以下 `if` 参数使用相同的运算符，但返回任意年份的 5 月份的记录，或者返回 2000 年 1 或 2 月份的记录。  

```
ifelse(month = 5 OR (month < 3 AND year = 2000), 'yes', 'no')
```

 *then-expression*   
在 *if* 参数的计算结果为 true 时，将返回该表达式。它可以是字段名称（如 **address1**）、文本值（如 **'Unknown'**）或对其他函数的调用。该表达式的数据类型必须与其他 `then` 参数和 `else` 参数相同。

 *else-expression*   
该表达式在所有 *if* 参数的计算结果都不为 true 时返回。它可以是字段名称（如 **address1**）、文本值（如 **'Unknown'**）或其他函数（如 `toString(salesAmount)`）。该表达式的数据类型必须与所有 `then` 参数相同。

## 返回类型


`ifelse` 返回与 *then-expression* 中的值具有相同数据类型的值。*then* 和 *else* 表达式返回的所有数据都必须是相同的数据类型或转换为相同的数据类型。

## 示例


以下示例为字段 `country` 生成一列别名。

```
ifelse(country = "United States", "US", country = "China", "CN", country = "India", "IN", "Others") 
```

对于此类用例，根据文本列表评估字段中的每个值，并返回与第一个匹配值相对应的结果，建议使用函数 switch 来简化您的工作。可以使用 [https://docs.amazonaws.cn/quicksight/latest/user/switch-function.html](https://docs.amazonaws.cn/quicksight/latest/user/switch-function.html) 将前面的示例重写为以下语句：

```
switch(country,"United States","US","China","CN","India","IN","Others")
```

以下示例将每位客户的销售额归类为人类可读的级别。

```
ifelse(salesPerCustomer < 1000, “VERY_LOW”, salesPerCustomer < 10000, “LOW”, salesPerCustomer < 100000, “MEDIUM”, “HIGH”)
```

以下示例使用 AND、OR 和 NOT 来比较多个表达式，表达式中使用了条件运算符，以标记不在华盛顿或俄勒冈州、享受特别促销并且订单超过 10 个的最大客户。如果没有返回值，则使用值 `'n/a'`。

```
ifelse(( (NOT (State = 'WA' OR State =  'OR')) AND Orders > 10),  'Special Promotion XYZ',  'n/a')
```

以下示例仅使用 OR 生成一个新列，该列包含与每个 `country` 对应的大洲名称。

```
ifelse(country = "United States" OR country = "Canada", "North America", country = "China" OR country = "India" OR country = "Japan", "Asia", "Others")
```

可以简化前面的示例，如下一个示例所示。以下示例使用 `ifelse` 和 [https://docs.amazonaws.cn/quicksight/latest/user/in-function.html](https://docs.amazonaws.cn/quicksight/latest/user/in-function.html) 在新列中为测试值位于文本列表中的任何行创建值。您也可以将 `ifelse` 与 [https://docs.amazonaws.cn/quicksight/latest/user/notIn-function.html](https://docs.amazonaws.cn/quicksight/latest/user/notIn-function.html) 搭配使用。

```
ifelse(in(country,["United States", "Canada"]), "North America", in(country,["China","Japan","India"]),"Asia","Others")
```

作者可以将文本列表保存在多值参数中，并在 [https://docs.amazonaws.cn/quicksight/latest/user/in-function.html](https://docs.amazonaws.cn/quicksight/latest/user/in-function.html) 或 [https://docs.amazonaws.cn/quicksight/latest/user/notIn-function.html](https://docs.amazonaws.cn/quicksight/latest/user/notIn-function.html) 函数中使用该参数。除了文本列表存储在两个多值参数中之外，以下示例与前面的示例相同。

```
ifelse(in(country,${NorthAmericaCountryParam}), "North America", in(country,${AsiaCountryParam}),"Asia", "Others") 
```

以下示例根据销售总额为销售记录分配一个组。每个 `if-then` 短语的结构都模仿了 *between* 的行为，这个关键字目前在计算字段表达式中不起作用。例如，比较 `salesTotal >= 0 AND salesTotal < 500` 的结果返回的值与 SQL 比较 `salesTotal between 0 and 499` 的值相同。

```
ifelse(salesTotal >= 0 AND salesTotal < 500, 'Group 1', salesTotal >= 500 AND salesTotal < 1000, 'Group 2', 'Group 3')
```

以下示例通过使用 `coalesce` 返回第一个非 NULL 值来测试 NULL 值。无需记住日期字段中 NULL 的含义，而是可以使用可读的描述来代替。如果断开连接日期为 NULL，则该示例将返回暂停日期，除非这两个日期均为 NULL。然后 `coalesce(DiscoDate, SuspendDate, '12/31/2491')` 返回 `'12/31/2491'`。返回值必须与其他数据类型匹配。这个日期可能看起来像是一个不寻常的值，但是 25 世纪的日期合理地模拟了“时间结束”，即数据集市中的最高日期。

```
ifelse (  (coalesce(DiscoDate, SuspendDate, '12/31/2491') = '12/31/2491'),  'Active subscriber', 'Inactive subscriber')
```

以下内容以更具可读性的格式显示了一个更复杂的示例，只是为了说明您不需要将代码全部压缩成一长行。此示例提供了对调查结果值的多重比较。它处理此字段的潜在 NULL 值，并对两个可接受的范围进行分类。它还会标记一个需要更多测试的范围和另一个无效（超出范围）的范围。对于所有剩余值，它会应用 `else` 条件，并将该行标记为在该行上的日期三年后需要重新测试。

```
ifelse
( 
    isNull({SurveyResult}), 'Untested',  
    {SurveyResult}=1, 'Range 1', 
    {SurveyResult}=2, 'Range 2', 
    {SurveyResult}=3, 'Need more testing',
    {SurveyResult}=99, 'Out of Range',
    concat  
    (
        'Retest by ', 
        toString    
        (
           addDateTime(3, "YYYY", {Date}) 
        )
    )
)
```

以下示例将“手动”创建的区域名称分配给一组州。它还使用空格和 `/* */` 中包装的注释来简化代码的维护。

```
ifelse 
(    /* NE REGION*/
     locate('New York, New Jersey, Connecticut, Vermont, Maine, Rhode Island, New Hampshire',{State}) > 0,
    'Northeast',

     /* SE REGION*/
     locate('Georgia, Alabama, South Carolina, Louisiana',{State}) > 0,
    'Southeast',

    'Other Region'
)
```

区域标记的逻辑分解如下：

1. 我们列出了要为每个区域设置的州，用引号将每个列表括起来，使每个列表成为一个字符串，如下所示：
   + `'New York, New Jersey, Connecticut, Vermont, Maine, Rhode Island, New Hampshire'`
   + `'Georgia, Alabama, South Carolina, Louisiana'`
   + 您可以添加更多设置，也可以根据需要使用国家/地区、城市、省份或 What3Words。

1. 我们询问列表中是否找到了 `State`（每行）的值，如果在列表中找到该州，则使用 `locate` 函数返回一个非零值，如下所示。

   ```
   locate('New York, New Jersey, Connecticut, Vermont, Maine, Rhode Island, New Hampshire',{State}) 
   
   and
   
   locate('Georgia, Alabama, South Carolina, Louisiana',{State})
   ```

1. `locate` 函数返回的是数字而不是 `TRUE` 或 `FALSE`，但 `ifelse` 需要使用 `TRUE`/`FALSE` 布尔值。为了解决这个问题，我们可以将 `locate` 的结果与一个数字进行比较。如果该州在列表中，则返回值大于零。

   1. 询问该州是否存在。

      ```
      locate('New York, New Jersey, Connecticut, Vermont, Maine, Rhode Island, New Hampshire',{State}) > 0
      ```

   1. 如果存在该区域，则将其标记为特定区域，在本例中为东北区域。

      ```
      /*The if expression:*/     locate('New York, New Jersey, Connecticut, Vermont, Maine, Rhode Island, New Hampshire',{State}) > 0,
      /*The then expression:*/   'Northeast',
      ```

1. 因为我们有不在列表中的州，也因为 `ifelse` 需要单个 `else` 表达式，所以我们提供 `'Other Region'` 作为剩余州的标签。

   ```
   /*The if expression:*/     locate('New York, New Jersey, Connecticut, Vermont, Maine, Rhode Island, New Hampshire',{State}) > 0,
   /*The then expression:*/   'Northeast',
   /*The else expression:*/   'Other Region'
   ```

1. 我们将所有这些都包装在 `ifelse( )` 函数中以获得最终版本。以下示例省略了原始版本中的东南区域的州。您可以重新添加这些州来代替 *`<insert more regions here>`* 标签。

   如果要添加更多区域，则可以构造这两行的更多副本，并根据自己的目的更改州列表。您可以将区域名称更改为适合自己的名称，也可以将字段名称从 `State` 更改为所需的任何名称。

   ```
   ifelse 
   (
   /*The if expression:*/     locate('New York, New Jersey, Connecticut, Vermont, Maine, Rhode Island, New Hampshire',{State}) > 0,
   /*The then expression:*/   'Northeast',
   
   /*<insert more regions here>*/
   
   /*The else expression:*/   'Other Region'
   )
   ```
**注意**  
还有其他方法可以对 if 表达式进行初始比较。例如，假设您提出了一个问题：“这个列表中没有缺少哪些州？” 而不是“列表上有哪些州？” 如果您这样做，可能会用不同的措辞。您可以将 locate 语句与零进行比较以查找列表中缺少的值，然后使用 NOT 运算符将它们归类为“未缺失”，如下所示。  

   ```
   /*The if expression:*/      NOT (locate('New York, New Jersey, Connecticut, Vermont, Maine, Rhode Island, New Hampshire',{State}) = 0),
   ```
两个版本都是正确的。您选择的版本应该对您和您的团队最有意义，这样您就可以轻松对其进行维护。如果所有选项看起来都相同，请选择最简单的选项。