简体   繁体   English

某种循环将 NULL 值移动到多列中的最后一列?

[英]Some sort of loop to move NULL values to last column in a number of columns?

I'm returning 4 columns in my query, each of which can contain information or be a NULL value.我在查询中返回 4 列,每列都可以包含信息或为 NULL 值。 Is there a way to create some sort of loop so that for each row, all the non-NULL values are moved the left most columns with the NULLs at the end?有没有办法创建某种循环,以便对于每一行,所有非 NULL 值都移动到最左边的列,最后有 NULL? Or perhaps with the use of functions?或者也许使用函数?

My situation:我的情况:

Value 1值 1 Value 2价值 2 Value 3价值 3 Value 4价值 4
5 5 3 3 NULL无效的 1 1
6 6 NULL无效的 NULL无效的 3 3

My desired result:我想要的结果:

Value 1值 1 Value 2价值 2 Value 3价值 3 Value 4价值 4
5 5 3 3 1 1 NULL无效的
6 6 3 3 NULL无效的 NULL无效的

Despite the interesting comments, this can be done, probably in most RDMS as long as they support array functions.尽管有一些有趣的评论,但这可能在大多数 RDMS 中都可以做到,只要它们支持数组函数。 (There will be variation in how it's done). (它的完成方式会有所不同)。 I made the example table more complicated to show more possible cases.我使示例表更复杂,以显示更多可能的情况。


Schema (PostgreSQL v13)架构 (PostgreSQL v13)

CREATE TABLE t (
  "value_1" INTEGER,
  "value_2" INTEGER,
  "value_3" INTEGER,
  "value_4" INTEGER
);

INSERT INTO t
  ("value_1", "value_2", "value_3", "value_4")
VALUES
  ('5', '3', null, '1'),
  ('6', null, null, '3'),
  ('3', '2', '1', '0'),
  (null, '2', null, '4'),
  (null, null, '3', '4'),
  (null, '3', '4', '5'),
  (null, null, null, '4');

Query询问

SELECT all_vals[1] Value_1
     , all_vals[2] Value_2
     , all_vals[3] Value_3
     , all_vals[4] Value_4
FROM (
    SELECT array_remove(ARRAY[value_1, value_2, value_3, value_4], NULL) all_vals
    FROM t
) arrs;
value_1值_1 value_2价值_2 value_3值_3 value_4 value_4
5 5 3 3 1 1
6 6 3 3
3 3 2 2 1 1 0 0
2 2 4 4
3 3 4 4
3 3 4 4 5 5
4 4

View on DB Fiddle在 DB Fiddle 上查看


Schema (MySQL v8.0)架构 (MySQL v8.0)

CREATE TABLE t (
  `value_1` INTEGER,
  `value_2` INTEGER,
  `value_3` INTEGER,
  `value_4` INTEGER
);

INSERT INTO t
  (`value_1`, `value_2`, `value_3`, `value_4`)
VALUES
  ('5', '3', null, '1'),
  ('6', null, null, '3'),
  ('3', '2', '1', '0'),
  (null, '2', null, '4'),
  (null, null, '3', '4'),
  (null, '3', '4', '5'),
  (null, null, null, '4');

Query询问

SELECT all_values -> "$[0]" value_1
     , all_values -> "$[1]" value_2
     , all_values -> "$[2]" value_3
     , all_values -> "$[3]" value_4
FROM ( -- The Ordering here matters, as they appear to change the index when removed, so I had to work back to front. 
       -- $[4] (Or any value outside the range) is necessary, as a NULL will cause the whole thing to return NULL.
  SELECT JSON_REMOVE(JSON_ARRAY(value_1, value_2, value_3, value_4) 
                     , CASE WHEN value_4 IS NULL THEN "$[3]" ELSE "$[4]" END
                     , CASE WHEN value_3 IS NULL THEN "$[2]" ELSE "$[4]" END
                     , CASE WHEN value_2 IS NULL THEN "$[1]" ELSE "$[4]" END
                     , CASE WHEN value_1 IS NULL THEN "$[0]" ELSE "$[4]" END
                    ) all_values
  FROM t) arr;
value_1值_1 value_2价值_2 value_3值_3 value_4 value_4
5 5 3 3 1 1
6 6 3 3
3 3 2 2 1 1 0 0
2 2 4 4
3 3 4 4
3 3 4 4 5 5
4 4

View on DB Fiddle在 DB Fiddle 上查看

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM