在 MySQL 查询中检查修剪字符串是否为假的正确方法是什么?

What is the proper way of checking for falsyness of trimmed strings in MySQL queries?

假设我有一个名为 users 的 table,包含三列 - id、name 和 nickname。

+----+---------+----------------+
| id |  name   | nickname       |
+----+---------+----------------+
|  1 | Alice   | Allie          |
|  2 | Bob     | B              |
|  3 | Charles |       Charlie  |
+----+---------+----------------+

我想显示连接的姓名和昵称(均已修剪),如果昵称在修剪后不是空字符串。如果截取的昵称为空,则只显示姓名。

我试过这样做:

SELECT
  users.id,
  CONCAT(
    TRIM(users.name),
    IF(
      TRIM(users.nickname),
      CONCAT(' - ',TRIM(users.nickname)),
      ''
    )
  )
FROM users

期待 return 这个

Alice Allie
Bob B
Charles Charlie

但是,只有名字是 returned,昵称不是。我究竟做错了什么?可以找到合适的 fiddle here.

CONCAT_WS 应该可以解决问题。它会跳过 NULL 值,但您明确需要处理空字符串:

SELECT CONCAT_WS('-'
               , NULLIF(TRIM(users.name), '')
               , NULLIF(TRIM(users.nickname), ''))
FROM users

在MySQL中,字符串的truth/false等同于是否可以将字符串强制转换为整数。如果字符串转换为整数 0,则为 "false"。如果字符串转换为 0 以外的任何值,则为 "true".

在MySQL中将字符串转换为整数意味着读取任何前导数字并使用数值。如果没有前导数字,则假设为 0,即 "false".

mysql> select 'abc123' + 0;
+--------------+
| 'abc123' + 0 |
+--------------+
|            0 |
+--------------+

mysql> select '123abc' + 0;
+--------------+
| '123abc' + 0 |
+--------------+
|          123 |
+--------------+

在您的情况下,您正在测试 IF(TRIM(users.nickname), <true-expr>, <false-expr>) 但昵称很可能不是以数字开头(除非用户是说唱艺术家 :-),因此它们都将被转换为 0,所以它们将导致 "false" 表达式。

如果您要测试字符串的长度,您应该这样做:

IF(LENGTH(TRIM(user.nickname) > 0, <true-expr>, <false-expr>)

@SalmanA 的回答是产生您想要的结果的一个很好的替代方法,但我写这个回答是为了解释为什么您会看到您看到的行为。