在 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 的回答是产生您想要的结果的一个很好的替代方法,但我写这个回答是为了解释为什么您会看到您看到的行为。
假设我有一个名为 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 的回答是产生您想要的结果的一个很好的替代方法,但我写这个回答是为了解释为什么您会看到您看到的行为。