使用 JOIN 或 UNION 将其他 MariaDB 表中的数据插入或更新 MariaDB 表

Complex INSERT or UPDATE MariaDB tables with data from other MariaDB tables using JOIN or UNION

我需要使用来自其他 table 的数据在 table 中插入或更新数据;我懂基本的

insert into table (a,b,c) 
select h, i, j 
from otherTable 
where........

我的挑战来自这样一个事实,即数据分布在多个 table 中,而在其中一个 table 中,数据是以行而非列形式存储的元数据。因此我需要使用 JOIN 和可能的 UNION 来获得所需的东西。

不幸的是,在尝试了我在 Maria 手册、Maria 论坛和 Stack overflow 上阅读的所有内容后,我无法让它工作。

这是我正在尝试做的事情:

使用源数据将数据插入以下字段的 dbc_jot_groupmembers 中:

jot_grpid = dbc_bp_groups_members.group_id
jot_bbmemid = dbc_bp_groups_members.user_id  
jot_grpmemname = dbc_bp_xprofile_data.value where field_id=3
jot_grpmemnum = dbc_bp_xprofile_data.value where field_id=4

我需要最终结果如下所示:

select * from dbc_jot_groupmembers;

+--------------+-----------+----------------+---------------+---------------------+-------------+
| jot_grpmemid | jot_grpid | jot_grpmemname | jot_grpmemnum | jot_grpmemts        | jot_bbmemid |
+--------------+-----------+----------------+---------------+---------------------+-------------+
|            1 |        17 | hutchdad       | +17047047045  | 2021-06-15 14:56:19 |        14   |
|            2 |        24 | hutchdad       | +17047047045  | 2021-06-15 19:49:58 |        14   |
|            3 |        25 | hutchdad       | +17047047045  | 2021-06-15 19:49:58 |        14   |
|            4 |        17 | hutchmom       | +17773274355  | 2021-06-15 19:49:58 |        15   |
|            5 |        24 | hutchmom       | +17773274355  | 2021-06-15 19:49:58 |        15   |
|            6 |        16 | ledwards       | +14567655645  | 2021-06-15 19:49:58 |        11   |
|            7 |        16 | medwards       | +12223334545  | 2021-06-15 19:49:58 |        10   |
|            7 |        20 | medwards       | +12223334545  | 2021-06-15 19:49:58 |        10   |

源表中的示例数据和 TABLE 定义:


MariaDB [devDisciplePlaceCom]> describe dbc_bp_groups_members;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| id            | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| group_id      | bigint(20)   | NO   | MUL | NULL    |                |
| user_id       | bigint(20)   | NO   | MUL | NULL    |                |
| inviter_id    | bigint(20)   | NO   | MUL | NULL    |                |
| is_admin      | tinyint(1)   | NO   | MUL | 0       |                |
| is_mod        | tinyint(1)   | NO   | MUL | 0       |                |
| user_title    | varchar(100) | NO   |     | NULL    |                |
| date_modified | datetime     | NO   |     | NULL    |                |
| comments      | longtext     | NO   |     | NULL    |                |
| is_confirmed  | tinyint(1)   | NO   | MUL | 0       |                |
| is_banned     | tinyint(1)   | NO   |     | 0       |                |
| invite_sent   | tinyint(1)   | NO   |     | 0       |                |
+---------------+--------------+------+-----+---------+----------------+
12 rows in set (0.002 sec)
 describe dbc_bp_xprofile_data;
+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| id           | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| field_id     | bigint(20) unsigned | NO   | MUL | NULL    |                |
| user_id      | bigint(20) unsigned | NO   | MUL | NULL    |                |
| value        | longtext            | NO   |     | NULL    |                |
| last_updated | datetime            | NO   |     | NULL    |                |
+--------------+---------------------+------+-----+---------+----------------+
5 rows in set (0.001 sec)

这是群组列表以及它们所在的用户。

select group_id,user_id  from dbc_bp_groups_members ;

+----------+---------+
| group_id | user_id |
+----------+---------+
|       16 |      13 |
|       16 |      12 |
|       16 |      11 |
|       16 |      10 |
|       17 |      14 |
|       17 |      15 |
|       17 |      16 |
|       17 |      17 |
|       17 |      18 |
|       17 |      19 |
|       20 |      10 |
|       24 |      14 |
|       24 |      16 |
|       24 |      15 |
|       24 |      17 |
|       24 |      19 |
|       25 |      19 |
|       25 |      14 |
|        1 |      14 |
|       11 |      14 |
+----------+---------+
20 rows in set (0.000 sec)

这是包含用户元数据的 TABLE。在我的例子中,我需要 PHOEN 编号和名称,它们位于值字段中,field_id 为 3 和 4。

select * from dbc_bp_xprofile_data where user_id > 9 and field_id > 2 AND field_id < 5;

+-----+----------+---------+---------------+---------------------+
| id  | field_id | user_id | value         | last_updated        |
+-----+----------+---------+---------------+---------------------+
|  31 |        3 |      10 | medwards      | 2021-06-24 03:11:59 |
|  34 |        3 |      11 | ledwards      | 2021-06-24 03:11:24 |
|  37 |        3 |      12 | nedwards      | 2021-04-24 14:47:18 |
|  40 |        3 |      13 | iedwards      | 2021-04-24 14:47:52 |
|  43 |        3 |      14 | hutchdad      | 2021-06-21 14:53:08 |
|  46 |        3 |      15 | hutchmom      | 2021-06-24 03:10:58 |
|  49 |        3 |      16 | hutchdaughter | 2021-04-24 16:54:48 |
|  52 |        3 |      17 | hutchson1     | 2021-04-24 16:55:43 |
|  55 |        3 |      18 | hutchson2     | 2021-04-24 16:57:42 |
|  58 |        3 |      19 | hutchson3     | 2021-04-24 16:58:44 |
|  78 |        3 |      25 | demoadmin     | 2021-06-08 02:01:39 |
| 158 |        4 |      14 | 7047047045    | 2021-06-21 14:53:08 |
| 190 |        3 |      58 | dupdup        | 2021-06-23 19:46:19 |
| 191 |        4 |      15 | 7773274355    | 2021-06-24 03:10:58 |
| 193 |        4 |      11 | 4567655645    | 2021-06-24 03:11:24 |
| 195 |        4 |      10 | 2223334545    | 2021-06-24 03:11:59 |
+-----+----------+---------+---------------+---------------------+
16 rows in set (0.000 sec)

如果这不能通过单个 INSERT 完成,那么我可以使用 INSERT 和后续的 UPDATE 语句。我也明白这不是最佳实践并且违反了 3nf 和可能的其他几个最佳实践原则。不幸的是,我受制于应用程序,无法更改代码,所以唯一的方法就是将重复数据放入数据库中,如下所述:

一个INSERT就可以完成。但是,有一些信息需要解决,就像我在评论中发布的那样。同时,这里是一个示例查询,您可以使用它来执行您想要的操作:

SELECT  ROW_NUMBER() OVER (ORDER BY A.group_id, A.user_id) AS 'jot_grpmemid',
        A.group_id AS 'jot_grpid', 
        MAX(CASE WHEN B.field_id=3 THEN B.value ELSE '' END) AS 'jot_grpmemname',
        MAX(CASE WHEN B.field_id=4 THEN CONCAT('+',B.value) ELSE '' END) AS 'jot_grpmemnum', 
        A.user_id AS 'jot_bbmemid'
 FROM
dbc_bp_groups_members A JOIN dbc_bp_xprofile_data B
ON A.user_id=B.user_id
GROUP BY A.group_id, A.user_id;

就像我在评论中所说的那样,我不确定您如何 get/generate jot_grpmemid 因为您的预期结果中有两个 7 所以我认为这是一个错字。我想,此时您可以相应地修改查询。

Demo fiddle