mariadb complex 根据公共列组合 table 列,并在输出的公共列中找不到时添加新列

mariadb complex combine table columns based on common columns and add new column when not found in common columns on output

我有 3 个 table 如下所示。其中 id、fcd、ref 列在 table 中很常见,我试图将所有 tables 列 table 组合成单个 table.

MariaDB [test]> select * from t1;
+----+-----+-----+------+------+
| id | fcd | ref | c1   | c2   |
+----+-----+-----+------+------+
|  1 |   1 | 1.0 | 0.10 | 2.00 |
|  1 |   2 | 1.5 | 0.40 | 2.22 |
|  3 |   1 | 2.0 | 0.10 | 4.30 |
|  3 |   2 | 3.2 | 0.01 | 6.60 |
|  5 |   3 | 7.5 | 0.00 | 7.70 |
+----+-----+-----+------+------+
5 rows in set (0.001 sec)

MariaDB [test]> select * from t2;
+----+-----+------+------+------+
| id | fcd | ref  | c3   | c4   |
+----+-----+------+------+------+
|  1 |   1 | 1.00 | 0.06 | 0.76 |
|  1 |   2 | 1.20 | 0.32 | 0.87 |
|  5 |   2 | 6.50 | 0.44 | 0.09 |
|  5 |   3 | 6.68 | 0.47 | 0.08 |
+----+-----+------+------+------+
4 rows in set (0.001 sec)

MariaDB [test]> select * from t3;
+----+-----+-----+------+------+
| id | fcd | ref | c5   | c6   |
+----+-----+-----+------+------+
|  1 |   3 | 1.1 | 0.02 | 0.12 |
|  1 |   4 | 2.0 | 0.23 | 0.11 |
|  7 |   1 | 3.2 | 0.45 | 0.43 |
|  7 |   2 | 7.5 | 0.54 | 0.67 |
+----+-----+-----+------+------+
4 rows in set (0.000 sec)

这是我尝试使用 union 时遇到的问题

MariaDB [test]> select id,fcd,ref,c1,c2,null c3, null c4, null c5, null c6 from t1  union all  select id,fcd,ref,null c1, null c2, c3, c4,null c5, null c6 from t2 union all select id,fcd,ref,null c1, null c2, null c3, null c4,c5, c6 from t3 order by id, fcd, ref;
+----+-----+------+------+------+------+------+------+------+
| id | fcd | ref  | c1   | c2   | c3   | c4   | c5   | c6   |
+----+-----+------+------+------+------+------+------+------+
|  1 |   1 | 1.00 | NULL | NULL | 0.06 | 0.76 | NULL | NULL |
|  1 |   1 | 1.00 | 0.10 | 2.00 | NULL | NULL | NULL | NULL |
|  1 |   2 | 1.20 | NULL | NULL | 0.32 | 0.87 | NULL | NULL |
|  1 |   2 | 1.50 | 0.40 | 2.22 | NULL | NULL | NULL | NULL |
|  1 |   3 | 1.10 | NULL | NULL | NULL | NULL | 0.02 | 0.12 |
|  1 |   4 | 2.00 | NULL | NULL | NULL | NULL | 0.23 | 0.11 |
|  3 |   1 | 2.00 | 0.10 | 4.30 | NULL | NULL | NULL | NULL |
|  3 |   2 | 3.20 | 0.01 | 6.60 | NULL | NULL | NULL | NULL |
|  5 |   2 | 6.50 | NULL | NULL | 0.44 | 0.09 | NULL | NULL |
|  5 |   3 | 6.68 | NULL | NULL | 0.47 | 0.08 | NULL | NULL |
|  5 |   3 | 7.50 | 0.00 | 7.70 | NULL | NULL | NULL | NULL |
|  7 |   1 | 3.20 | NULL | NULL | NULL | NULL | 0.45 | 0.43 |
|  7 |   2 | 7.50 | NULL | NULL | NULL | NULL | 0.54 | 0.67 |
+----+-----+------+------+------+------+------+------+------+
13 rows in set (0.001 sec)

上面一个没有正确组合,你可以看到 1 | 1 | 1 有重复的

这就是我所期望的

| id    | fcd   | ref   | c1    | c2    | c3    | c4    | c5    | c6    |
|----   |-----  |------ |------ |------ |------ |------ |------ |------ |
| 1     | 1     | 1     | 0.1   | 2     | 0.06  | 0.76  | NULL  | NULL  |
| 1     | 2     | 1.2   | NULL  | NULL  | 0.32  | 0.87  | NULL  | NULL  |
| 1     | 2     | 1.5   | 0.4   | 2.22  | NULL  | NULL  | NULL  | NULL  |
| 1     | 3     | 1.1   | NULL  | NULL  | NULL  | NULL  | 0.02  | 0.12  |
| 1     | 4     | 2     | NULL  | NULL  | NULL  | NULL  | 0.23  | 0.11  |
| 3     | 1     | 2     | 0.1   | 4.3   | NULL  | NULL  | NULL  | NULL  |
| 3     | 2     | 3.2   | 0.01  | 6.6   | NULL  | NULL  | NULL  | NULL  |
| 5     | 2     | 6.5   | NULL  | NULL  | 0.44  | 0.09  | NULL  | NULL  |
| 5     | 3     | 6.68  | NULL  | NULL  | 0.47  | 0.08  | NULL  | NULL  |
| 5     | 3     | 7.5   | 0     | 7.7   | NULL  | NULL  | NULL  | NULL  |
| 7     | 1     | 3.2   | NULL  | NULL  | NULL  | NULL  | 0.45  | 0.43  |
| 7     | 2     | 7.5   | NULL  | NULL  | NULL  | NULL  | 0.54  | 0.67  |

求大神帮帮我,不知道怎么解决

您可以group by id,fcd,ref查询和汇总结果:

select id,fcd,ref,max(c1) c1,max(c2) c2,max(c3) c3,max(c4) c4,max(c5) c5,max(c6) c6 
from (  
  select id,fcd,ref,c1,c2,null c3, null c4, null c5, null c6 from t1  
  union all  
  select id,fcd,ref,null c1, null c2, c3, c4,null c5, null c6 from t2 
  union all 
  select id,fcd,ref,null c1, null c2, null c3, null c4,c5, c6 from t3 
) t
group by id,fcd,ref
order by id,fcd,ref;

参见demo

通过在 idfcdref 列上使用 UNION 而不是 UNION ALL,您可以获得相同的结果:

SELECT t.id,
       t.fcd,
       t.ref,
       t1.c1,
       t1.c2,
       t2.c3,
       t2.c4,
       t3.c5,
       t3.c6
FROM
  (SELECT id,
          fcd,
          ref
   FROM t1
   UNION SELECT id,
                fcd,
                ref
   FROM t2
   UNION SELECT id,
                fcd,
                ref
   FROM t3) AS t
LEFT JOIN t1 USING(id,
                   fcd,
                   ref)
LEFT JOIN t2 USING(id,
                   fcd,
                   ref)
LEFT JOIN t3 USING(id,
                   fcd,
                   ref)
ORDER BY id,
         fcd,
         ref;

ref: fiddle(感谢@forpas 提供基础数据)