【问题标题】:How to insert one row of a table into two rows of another table如何将表格的一行插入另一个表格的两行
【发布时间】:2018-11-07 23:49:21
【问题描述】:

我在表 Table1 中有一条记录,我想将该记录拆分为两行并插入到另一个表 Table2 中。

表1

ID  Date      User       value
1   29/05/18   XXX   X_ID||X_value||22||xx
2   29/05/18   YYY   Y_ID||Y_value||33|yy

我希望将 table1 值插入到 table2 中

表2

P_ID ID Date       User   Field    Value
 1   1  29/05/18    XXX    X_ID     22
 2   1  29/05/18    XXX    X_Value  XX
 3   2  29/05/18    YYY    Y_ID     33
 4   3  29/05/18    YYY    Y_Value  YY

table1 中的值是 table2 中的字段,没有什么可以硬编码,因为我在 table1 中有很多记录。 编辑:如果表 1 中的值具有更多值,例如 X_ID||X_VALUE||Y_ID||Y_Value||22||xx||33||yy,该怎么办?如何使此查询动态化,以便无论输出如何,它都会将 table2 不同行中的记录分开

【问题讨论】:

  • Table1的记录中是否有可能多于或少于2个(字段,值)或者值列的格式是否固定?
  • 创建一个包含 2 个“虚拟”行的临时表,与临时表连接,为每个虚拟行选择正确的列。或者使用联合选择两次
  • 这完全取决于你,但你为什么要把它分成两个行,而不是两个列,比如(ID、日期、用户, X, Y)?
  • 我在问,因为你的表 2 看起来有点像EAV
  • 这是需要的@wolφi

标签: sql oracle


【解决方案1】:

你可以使用regexp_substr():

select id, date, user, regexp_substr(val, '[^|]+', 1, 1) as field, regexp_substr(val, '[^|]+', 1, 3) as value
from table1
union all
select id, date, user, regexp_substr(val, '[^|]+', 1, 2) as field, regexp_substr(val, '[^|]+', 1, 4) as value
from table1;

您可以使用insert 将其放入另一个表中。这假定p_id 是自动分配的。如果要自己分配,可以使用row_number():

select row_number() over (partition by id order by which) as p_id,
       id, date, user, field, value
from ((select id, date, user, regexp_substr(val, '[^|]+', 1, 1) as field, regexp_substr(val, '[^|]+', 1, 3) as value, 1 as which
       from table1
      ) union all
      (select id, date, user, regexp_substr(val, '[^|]+', 1, 2) as field, regexp_substr(val, '[^|]+', 1, 4) as value, 2 as which
       from table1
      )
     ) t

【讨论】:

  • 对于 p_id 我正在尝试创建序列,但由于不允许使用序列而出现错误。 @linoff 戈登。并且 row_number() 可以减慢这个过程,因为我要处理很多行。我们还有其他替代方法来自动生成 p_id。
  • @SYMA 。 . .我不确定为什么不允许序列。也许你应该问另一个问题。
  • 如果table1中的值有更多的值,比如X_ID||X_VALUE||Y_ID||Y_Value||22||xx||33||yy,你能帮忙吗?如何使此查询动态化,以便无论输出如何,它都会将 table2 不同行中的记录分开
【解决方案2】:

我已经尝试通过使用游标来解决这个问题。

声明@ID INT

声明@NAME VARCHAR(50)

声明@DATE日期

声明@VALUE VARCHAR(500)

DECLARE @List TABLE(项目 NVARCHAR(MAX))

声明@SELECTCURSOR 光标

SET @SELECTCURSOR = CURSOR FOR SELECT * FROM tempTable1

打开@SELECTCURSOR

从@SELECTCURSOR 获取下一个到@ID、@DATE、@NAME、@VALUE

WHILE @@FETCH_STATUS = 0

开始

SET @VALUE = 替换(@VALUE, '||', '.');

INSERT INTO tempTable2(ID,[User],[Date],Field,Value) VALUES(@ID,@NAME,@DATE,ParseName(@VALUE,4),PARSENAME(@VALUE,2))

INSERT INTO tempTable2(ID,[User],[Date],Field,Value) VALUES(@ID,@NAME,@DATE,ParseName(@VALUE,3),PARSENAME(@VALUE,1))

从@SELECTCURSOR 获取下一个到@ID、@DATE、@NAME、@VALUE

结束

关闭@SELECTCURSOR

解除@SELECTCURSOR

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-11
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 2015-05-14
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多