从所有列中选择最后(最近)填充值

时间:2017-09-17 07:09:20

标签: mysql sql select

我有一张桌子,说明表格为:

| ID | SNO |  c1   |  c2  |  c3   |
___________________________________
| 1  |  1  |  c11  | c21  |  c31  |
| 1  |  2  |  NULL | c22  |  c32  |
| 1  |  3  |  NULL | NULL |  c33  |



现在,我需要的是:

|  c1   |  c2  |  c3   |
________________________
|  c11  |  c22 |  c33  |

表示:特定参考的每列的最后插入值,在本例中为ID = 1

我已经通过this链接,WITH子句,但无法理解和使用,因为MySQL 8.0不受服务器支持。

2 个答案:

答案 0 :(得分:2)

您可以执行以下操作,以便为每个组选择最新的非空值

select ID,
SUBSTRING_INDEX(group_concat(c1 order by SNO desc),',',1) c1,
SUBSTRING_INDEX(group_concat(c2 order by SNO desc),',',1) c2,
SUBSTRING_INDEX(group_concat(c3 order by SNO desc),',',1) c3
from demo
group by ID

DEMO

修改

要获得每列的SNO,您可以更新您的查询,如下所示

select ID,
substring_index(group_concat(c1 order by SNO desc),',',1) c1,
substring_index(group_concat(case when c1 is not null then SNO end  order by SNO desc),',',1) sno1,
substring_index(group_concat(c2 order by SNO desc),',',1) c2,
substring_index(group_concat(case when c2 is not null then SNO end  order by SNO desc),',',1) sno2,
substring_index(group_concat(c3 order by SNO desc),',',1) c3,
substring_index(group_concat(case when c3 is not null then SNO end  order by SNO desc),',',1) sno3
from demo
where ID = 1
group by ID

DEMO

答案 1 :(得分:0)

您可能不希望使用substring_index() / group_concat()的原因有多种。我建议在预订时使用它:

  • 这些值可能包含逗号(然后您可能需要使用分隔符)。
  • group_concat()的内部缓冲区可能会溢出。
  • 您可能不希望将非字符串值的类型更改为字符串。

另一种选择值得一提。您可以使用聚合获取每列的最大sno

select id,
       max(case when c1 is not null then sno end) as c1_sno,
       max(case when c2 is not null then sno end) as c2_sno,
       max(case when c3 is not null then sno end) as c3_sno
from t
group by id;

带入实际值只是使用join

的问题
select id, t1.c1, c2.c2, t3.c3
from (select id,
             max(case when c1 is not null then sno end) as c1_sno,
             max(case when c2 is not null then sno end) as c2_sno,
             max(case when c3 is not null then sno end) as c3_sno
      from t
      group by id
     ) t left join
     t t1
     on t1.c1_sno = t.c1_sno left join
     t t2
     on t2.c2_sno = t.c2_sno left join
     t t3
     on t3.c3_sno = t.c3_sno;

如果您要针对特定​​id过滤此内容,而对子查询中的where进行过滤。