【问题标题】:Aggregating values from the UNION set operator [closed]聚合来自 UNION 集合运算符的值 [关闭]
【发布时间】:2019-09-09 11:45:33
【问题描述】:

我们应该如何聚合值,以防万一,如果单个列中有两个值并且其余列包含 NULL 值,则需要对所有值进行分组以及列的其余部分应显示NULL 作为值

如果单个列中有两个值并且其余列包含 NULL 值,则我们需要迭代每个列值,移动到顶部并将 NULL 值下一个/底部移动到该特定值,然后所有值需要移动到顶部,将剩余的 NULL 值留在底部,如果一行中没有值,那么它应该简单地显示为 NULL

考虑简单的 SQL 查询

SELECT
  *
FROM
  (
    (SELECT
      6 + 2 AS val1,
      NULL AS val2,
      NULL AS val3,
      NULL AS val4,
      5 + 5 AS val5,
      NULL AS val6
    FROM
      DUAL)
    UNION
    (SELECT
      NULL AS val1,
      6 - 2 AS val2,
      NULL AS val3,
      NULL AS val4,
      9 - 3 AS val5,
      7 - 3 AS val6
    FROM
      DUAL)
    UNION
    (SELECT
      NULL AS val1,
      NULL AS val2,
      6 * 2 AS val3,
      NULL AS val4,
      NULL AS val5,
      NULL AS val6
    FROM
      DUAL)
    UNION
    (SELECT
      NULL AS val1,
      NULL AS val2,
      NULL AS val3,
      6 / 2 AS val4,
      NULL AS val5,
      NULL AS val6
    FROM
      DUAL)
  ) A;

实际结果:

+------+------+------+--------+------+------+
| val1 | val2 | val3 | val4   | val5 | val6 |
+------+------+------+--------+------+------+
|    8 | NULL | NULL |   NULL |   10 | NULL |
| NULL |    4 | NULL |   NULL |    6 |    4 |
| NULL | NULL |   12 |   NULL | NULL | NULL |
| NULL | NULL | NULL | 3.0000 | NULL | NULL |
+------+------+------+--------+------+------+
4 rows in set (0.00 sec)

预期结果:

+------+------+------+--------+------+------+
| val1 | val2 | val3 | val4   | val5 | val6 |
+------+------+------+--------+------+------+
|    8 |    4 | 12   | 3.0000 |   10 |    4 |
| NULL | NULL | NULL |   NULL |    6 | NULL |
+------+------+------+--------+------+------+
1 row in set (0.00 sec)

SQL Demo

编辑:

正如 Gordon Linoff 所说,在 MySQL 8+ 中可以使用 row_number() 和 joins 正如我期望通过 SQL Demo 获得满足预期结果的精确解决方案一样。因为帖子被搁置了

【问题讨论】:

  • SQL 表表示 无序 集,因此除非列指定排序,否则不会“向上移动”。
  • 我们应该如何处理这种情况@GordonLinoff
  • 为什么你还需要这样做?请告诉实际用例。这不是关系数据(表)的工作方式;一行及其所有字段(列)连接在一起,作为特定数据;你不能像魔方一样让它们错位。

标签: mysql sql union sql-null


【解决方案1】:

在 MySQL 8+ 中,您可以使用 row_number() 并加入:

select t1.val1, t2.val2, t3.val3, . . .
from (select row_number() over (order by (val1 is not null asc) as seqnum, t.*
      from t
     ) t1 join
     (select row_number() over (order by (val2 is not null asc) as seqnum, t.*
      from t
     ) t2
     on t1.seqnum = t2.seqnum join
     (select row_number() over (order by (val3 is not null asc) as seqnum, t.*
      from t
     ) t3
     on t1.seqnum = t3.seqnum join
     . . .
order by t1.seqnum;

这不会保留行的原始顺序。它只是将NULL 值移动到“结束”。

【讨论】:

  • 你会尝试用这个SQL Demo运行吗?我不知道我应该如何采用我的 SQL
  • @Nishanthॐ 。 . .将您的值放入表格或使用 CTE。
  • 这意味着什么我们需要如何实现它
【解决方案2】:

你可以试试GROUP_CONCAT()

Select 
  GROUP_CONCAT(val1) as val1,
  GROUP_CONCAT(val2) as val2,
  GROUP_CONCAT(val3) as val3,
  GROUP_CONCAT(val4) as val4,
  GROUP_CONCAT(val5) as val5,
  GROUP_CONCAT(val6) as val6
FROM
  (
    (SELECT
      6 + 2 AS val1,
      NULL AS val2,
      NULL AS val3,
      NULL AS val4,
      5 + 5 AS val5,
      NULL AS val6
    FROM
      DUAL)
    UNION
    (SELECT
      NULL AS val1,
      6 - 2 AS val2,
      NULL AS val3,
      NULL AS val4,
      9 - 3 AS val5,
      7 - 3 AS val6
    FROM
      DUAL)
    UNION
    (SELECT
      NULL AS val1,
      NULL AS val2,
      6 * 2 AS val3,
      NULL AS val4,
      NULL AS val5,
      NULL AS val6
    FROM
      DUAL)
    UNION
    (SELECT
      NULL AS val1,
      NULL AS val2,
      NULL AS val3,
      6 / 2 AS val4,
      NULL AS val5,
      NULL AS val6
    FROM
      DUAL)
  ) A;

SQL Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 2023-02-24
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    相关资源
    最近更新 更多