请问像这样的一列一列的数据如何插入到一张表中,我利用select查询插入但是却不能并排插入,而是交错插入,请各位大佬帮忙解答一下

元观川 2023-10-18 16:29:54

 

 

 

 

 

...全文
767 5 打赏 收藏 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
AI向善 09-10 11:21
  • 打赏
  • 举报
回复

你问的是「社区 CSDN 开源数据库社区 Mysql社区 帖子详情 请问像这样的一列一列的数据如何插入到一张表」,我结合实操说几句。

最稳的起步是先把端到端链路打通,再谈优化。数据库建议从官方 quickstart 改起,每一步都有对照。
落地步骤一般是:① 跑通最小可用闭环;② 按你的场景替换数据/模型;③ 加监控和回退,再上量。
别一上来追指标和效果,链路没通就调参等于在沙子上盖楼。

以上是基于常见落地经验的判断,不一定全对。你那边具体是什么场景/报错?评论区说下,我帮你看。

AI向善 09-10 09:52
  • 打赏
  • 举报
回复

先说结论:关系型数据库是行存储,没有「按列插入」这个操作。你看到的「交错插入」,本质是两次 SELECT 出来的行序不一致,再按顺序拼到一起就错位了。

为什么会出现交错

如果你的写法类似这样:

INSERT INTO t (col_a) SELECT val FROM src_a;
INSERT INTO t (col_b) SELECT val FROM src_b;

这是在往同一列追加行,得到的是纵向堆叠而不是并排 —— 这是 SQL 的正常语义,不是写错了。

真正会「交错」的是这种:想按行号把两列拼起来,但没固定顺序:

-- 危险写法:行序不确定
SELECT a.val, b.val
FROM src_a a, src_b b
WHERE a.rn = b.rn;

rn 如果来自 ROW_NUMBER() OVER () 且不带 ORDER BY,两次查询的读序可能不同,于是第 1 行的 col_a 配到了第 3 行的 col_b,看起来就是交错。

正确的两条路

路线一:一次插多列(有共同 key 时优先)

INSERT INTO target (id, col_a, col_b)
SELECT a.id, a.val, b.val
FROM src_a a
JOIN src_b b ON a.id = b.id;

关键是 SELECT 的列顺序要和 INSERT 的列名顺序对齐,这是「并排」比较直接的做法。

如果目标表已经有行,只是缺列,用 UPDATE ... JOIN 补:

UPDATE target t JOIN src_a a ON t.id = a.id SET t.col_a = a.val;
UPDATE target t JOIN src_b b ON t.id = b.id SET t.col_b = b.val;

路线二:没有 key,只能靠行号对齐

那就必须把行序显式固定下来,否则很容易错位:

WITH a AS (SELECT val, ROW_NUMBER() OVER (ORDER BY id) rn FROM src_a),
     b AS (SELECT val, ROW_NUMBER() OVER (ORDER BY id) rn FROM src_b)
SELECT a.rn, a.val AS col_a, b.val AS col_b
FROM a JOIN b ON a.rn = b.rn;

ORDER BY 不能省,而且两张源表要用同一种排序依据,这样 rn 才对得上。

避坑

  • 别用逗号连接(隐式笛卡尔积),数据量一大就跑不动,还容易出重复行;
  • 拼之前先 SELECT COUNT(*) 比一下两边行数,行数不等时 JOIN 会静默丢行;
  • 如果两列数据本来就没有对应关系,那「并排」本身就是个伪需求,先确认业务上凭什么把它们配在一起。

怎么验证

先跑一遍不带 INSERT 的 SELECT,肉眼确认前 5 行左右对得上,再包进 INSERT。这样即使错了也只是白跑一次查询,不会污染目标表。

AI向善 09-09 16:11
  • 打赏
  • 举报
回复

你问的是「社区 CSDN 开源数据库社区 Mysql社区 帖子详情 请问像这样的一列一列的数据如何插入到一张表」,我结合实操说几句。

最稳的起步是先把端到端链路打通,再谈优化。数据库建议从官方 quickstart 改起,每一步都有对照。
落地步骤一般是:① 跑通最小可用闭环;② 按你的场景替换数据/模型;③ 加监控和回退,再上量。
别一上来追指标和效果,链路没通就调参等于在沙子上盖楼。

以上是基于常见落地经验的判断,不一定全对。你那边具体是什么场景/报错?评论区说下,我帮你看。

AI向善 09-09 09:51
  • 打赏
  • 举报
回复

你说的"一列一列的数据,用 SELECT 查出来插入却交错而不是并排",根因是:INSERT ... SELECT 是按行追加的,它每查一行就生成一行新记录。你现在是多次分别插入不同的列,数据库没法把后来插入的"列"自动拼到前面那行的同一行里——结果就是行越加越多,看起来成了"交错"。

要把多列数据并排进同一张表的同一行,关键是让它们在同一 INSERT 语句里按关联键 JOIN 起来,而不是分几次插。

场景一:数据本来就在库里,分属不同表/不同列
用 JOIN 把同一行的各列一次性查出来再插入:

INSERT INTO 目标表 (col_a, col_b, col_c)
SELECT t1.a, t2.b, t3.c
FROM 表1 t1
JOIN 2 t2 ON t1.主键 = t2.主键
JOIN 3 t3 ON t1.主键 = t3.主键;

这里 t1、t2、t3 通过主键对齐到同一行,插入后就是并排的,不会交错。

场景二:数据是几列独立的文本/临时表,没有明确主键
先给每一列编上"行号",再按行号 JOIN:

INSERT INTO 目标表 (col_a, col_b)
SELECT a.val, b.val
FROM (SELECT val, @r1:=@r1+1 rn FROM 列A, (SELECT @r1:=0) t) a
JOIN (SELECT val, @r2:=@r2+1 rn FROM 列B, (SELECT @r2:=0) t) b
  ON a.rn = b.rn;

行号对齐后,第 N 行的 A、B 就落到了目标表同一行。

场景三:本来就是一张表里的列,只是你想"补"几列
直接用 UPDATE 而不是 INSERT:

UPDATE 目标表 t
JOIN 来源表 s ON t.id = s.id
SET t.新列 = s.值;

这样是在已有行上并排补列,不会新增行。

记住一句话:要"并排"就必须在一条语句里、用关联键把各列对齐;分多次 INSERT 一定会变成逐行追加。先想清楚你的多列数据之间靠什么字段对应(主键、行号还是位置),选上面对应的写法就行。

huakaihualuohhl 2023-10-18
  • 打赏
  • 举报
回复

img

151

社区成员

发帖
与我相关
我的任务
社区描述
开源数据库
其他 其他
社区管理员
  • 数据库小助手
  • 灰小猿
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧