mysql - 在某些字段中折叠或覆盖具有空值的多行

标签 mysql sql

我有一张 table :

CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user` varchar(100) DEFAULT NULL,
  `priority` int(11) DEFAULT NULL,
  `val1` varchar(100) DEFAULT NULL,
  `val2` varchar(100) DEFAULT NULL,
  `val3` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `t` VALUES (1,'tj',1,'Set-1',NULL,NULL),(2,'tj',5,'Z-invalid','Set-2',NULL),(3,'tj',10,'a-invalid','Z-invalid','Set-3');

数据如下:

mysql> select * from t;
+----+------+----------+-----------+-----------+-------+
| id | user | priority | val1      | val2      | val3  |
+----+------+----------+-----------+-----------+-------+
|  1 | tj   |        1 | Set-1     | NULL      | NULL  |
|  2 | tj   |        5 | Z-invalid | Set-2     | NULL  |
|  3 | tj   |       10 | a-invalid | Z-invalid | Set-3 |
+----+------+----------+-----------+-----------+-------+

我想做的是按优先级排序,然后折叠或覆盖数据。如果列中的值为 NULL,则从下一个优先级最高的列中获取该值。如果字段不为空,则停在那里。

它最终应该是这样的:

+------+-----------+-----------+-------+
| user | val1      | val2      | val3  |
+------+-----------+-----------+-------+
| tj   | Set-1     | Set-2     | Set-3 |
+------+-----------+-----------+-------+

如果我只想获得一个字段,那会很容易 - 我会这样做

SELECT val1 FROM t WHERE user='tj' AND val1 IS NOT NULL ORDER BY priority ASC LIMIT 1;

但是我实际希望实现这个想法的表有大约 30 列,我不想做 30 种不同的选择。而且我不能使用 MAX,因为决定为每一列显示哪个值的是优先级,而不是列本身值的 MAX。

我在这里缺少某种聚合选项吗?

最佳答案

这有点 hack,需要检查每一行,所以如果你的表很大,性能会很糟糕,但你可以这样做:

set @val1 = NULL;
set @val2 = NULL;
set @val3 = NULL;

select @val1 AS val1, @val2 AS val2, @val3 AS val3
from
(
  select @val1 := COALESCE(@val1, val1) AS val1, 
         @val2 := COALESCE(@val2, val2) AS val2, 
         @val3 := COALESCE(@val3, val3) AS val3
  from t 
  order by priority asc
) x
limit 1

SQL Fiddle demo

关于mysql - 在某些字段中折叠或覆盖具有空值的多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18906568/

相关文章:

mysql - Docker容器运行supervisor过早关闭

mysql - MYSQL 中带时区的日期格式

php - 检查条目是否属于数据库

mysql - 如何选择给定数据出现在表中多行的行?

php - php中查询sql的语法

PHP、mysql boolean 搜索

mysql - VB.NET 将 24 小时 mySQL TIME() 转换为 12 小时格式

mysql - 有没有办法使用 MYSQL 中的 max() 函数创建多列?

SQL,关于join的问题

MySQL从多个子行查询相关实体到json数组中