我有一张桌子:
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,则从下一个最高优先级列中获取值。如果字段不为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。
我在这里缺少某种聚合选项吗?
答案 0 :(得分:0)
这有点像黑客,需要检查每一行,所以如果你的桌子很大,性能会很糟糕,但是你可以这样做:
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