【问题标题】:Missing null values in a GroupConcatGroupConcat 中缺少空值
【发布时间】:2020-09-20 14:52:52
【问题描述】:

我有一个表,我在其中注册事件开始和结束的时间。我想要一个在我的日期范围内结束或正在进行中的事件列表,但那些尚未结束的事件是错误的,因为组 concat 中缺少空值。

如何通过 entity_id 分组获得空值?

| id | entity_id | start                | end                  |
|----|-----------|----------------------|----------------------|
| 1  | 10        | 2020-05-22T23:50:00Z | 2020-05-23T00:15:00Z |
| 2  | 20        | 2020-05-22T23:30:00Z | 2020-05-23T00:50:00Z |
| 3  | 10        | 2020-05-23T01:00:00Z | 2020-05-23T01:10:00Z |
| 4  | 20        | 2020-05-23T01:30:00Z | 2020-05-23T01:50:00Z |
| 5  | 20        | 2020-05-23T02:00:00Z | null                 |
| 6  | 10        | 2020-05-23T05:00:00Z | null                 |

我的查询:

SELECT entity_id,   
SUBSTRING_INDEX(GROUP_CONCAT(`start` ORDER BY `start` DESC SEPARATOR '||'), '||', 1) AS `start`,
SUBSTRING_INDEX(GROUP_CONCAT(`end` ORDER BY `start` DESC SEPARATOR '||'), '||', 1) AS `end`
FROM my_table
WHERE `start` <= '2020-05-23 23:59:59'  
AND ( `end` IS NULL OR `end` BETWEEN '2020-05-23 00:00:00' AND '2020-05-23 23:59:59' )
GROUP BY entity_id ;

这是查询结果

| entity_id | start               | end                 |
|-----------|---------------------|---------------------|
| 10        | 2020-05-23 05:00:00 | 2020-05-23 01:10:00 |
| 20        | 2020-05-23 02:00:00 | 2020-05-23 01:50:00 |

但这是应​​该的

| entity_id | start               | end                 |
|-----------|---------------------|---------------------|
| 10        | 2020-05-23 05:00:00 | null                |
| 20        | 2020-05-23 02:00:00 | null                |

我创建了一个例子:http://sqlfiddle.com/#!9/e04be2/1/0

【问题讨论】:

  • 聚合函数都忽略空值。
  • GROUP_CONCAT() 跳过 NULL 值,这已记录在案: 此函数返回一个字符串结果,其中包含来自组的串联非 NULL 值。如果没有非 NULL 值,则返回 NULL。

标签: mysql group-by group-concat


【解决方案1】:

GROUP_CONCAT() 跳过 NULL 值。

您可以使用IFNULL 将空值转换为显式字符串'null'

SELECT entity_id,   
SUBSTRING_INDEX(GROUP_CONCAT(`start` ORDER BY `start` DESC SEPARATOR '||'), '||', 1) AS `start`,
SUBSTRING_INDEX(GROUP_CONCAT(IFNULL(`end`, 'null') ORDER BY `start` DESC SEPARATOR '||'), '||', 1) AS `end`
FROM my_table
WHERE `start` <= '2020-05-23 23:59:59'  
AND ( `end` IS NULL OR `end` BETWEEN '2020-05-23 00:00:00' AND '2020-05-23 23:59:59' )
GROUP BY entity_id ;

【讨论】:

  • 这可能有效,但不适用于这种特殊情况。在我的 api (java) 中,它不会映射到 java 模型,因为“end”是一个日期,而不是一个字符串。我需要 null,因为 null
  • 由于GROUP_CONCAT()返回一个字符串,你不能有一个实际的NULL值。
  • 即使是非空值也是字符串,不是日期。
  • @FranAguiar 使用外部NULLIF() 函数在SUBSTRING_INDEX 之后从'null' 恢复到null在我的 api (java) 中,它不会映射到 java 模型,因为“end”是日期,而不是字符串 没有什么可以阻止使用某些预定义的数据类型文字(例如,在遥远的将来) 作为“必须有空”标记。
  • 是的,我的想法是尝试这种方法,默认日期为未来。谢谢
猜你喜欢
  • 1970-01-01
  • 2022-06-30
  • 1970-01-01
  • 1970-01-01
  • 2013-11-02
  • 1970-01-01
  • 2015-01-01
  • 2011-12-08
  • 1970-01-01
相关资源
最近更新 更多