【问题标题】:how to insert multiple row in one table according to single row of another table?如何根据另一个表的单行在一个表中插入多行?
【发布时间】:2023-03-09 11:32:01
【问题描述】:

我有 2 张桌子,tr_testmodule 和 TR_Modulelocationdtl。

select * from tr_testmodule -output like below (nmoduleno is primary key, vlocationno is varchar)

    nmoduleno   vlocationnno          
    1           3,65,6,9,63        
    2           13,625,62,91,613    

现在我想将数据从 tr_testmodule 插入到 TR_Modulelocationdtl 中,用于 tr_testmodule 的每一行,只需要一个查询。

例如我想为单个模块插入多行

select * from TR_Modulelocationdtl --(nid is pk,nlocationo-int)

        nid nmoduleno   nlocationno
        1   1             3 
        2   1             65
        3   1             6
        4   1             9
        5   1             63
        6   2             13
        7   2             625

我可以将这样的数据从临时表中拆分为临时表(但仅限单行)我可以将数据插入到我的“TR_Modulelocationdtl”中

SELECT * INTO #TR_Modulelocationdtl FROM (SELECT data AS nLocationno FROM dbo.SplitString('1,23,2,3,5',',') ) AS nLocationno
select * from #TR_Modulelocationdtl 

nLocationno
1
23
2
3
5

【问题讨论】:

  • insert into t1 (col1, col2, ...) select cola, colb, ... from t2 where ...?
  • 现在我明白了,unpivot。好主意,因为逗号分隔的项目很乱,只会导致很多问题——我猜你刚刚注意到了。
  • @jarlh 你能用 unpivot 为我写查询吗
  • 您使用的是哪个 dbms? (您可能在这里需要特定于产品的功能。)
  • 抱歉,我不太了解 SQL Server。

标签: sql sql-server database


【解决方案1】:

试试这个:

DECLARE @t TABLE ( n INT, v VARCHAR(100) )
INSERT  INTO @t
VALUES  ( 1, '3,65,6,9,63' ),
        ( 2, '13,625,62,91,613' )


SELECT  n, s
FROM    @t
        CROSS APPLY ( SELECT    Split.a.value('.', 'VARCHAR(100)') AS s
                      FROM      ( SELECT    CAST ('<M>' + REPLACE(v, ',','</M><M>')
                                                  + '</M>' AS XML) AS s) AS A
                      CROSS APPLY s.nodes('/M') AS Split ( a )
                    ) ca   

输出:

n   s
1   3
1   65
1   6
1   9
1   63
2   13
2   625
2   62
2   91
2   613

【讨论】:

    【解决方案2】:

    使用存储过程(或匿名块)很容易解决这个问题:遍历当前在 tr_testmodule 中的记录,拆分 vlocationnno 并遍历由此获得的位置,然后插入到 tr_modulelocationdtl。

    我不太了解 SQL Server,所以这里有一个等效的 Oracle 脚本,可以用作伪代码。我猜应该很容易将其转换为 SQL Server。

    begin
      for rec in (select * from tr_testmodule) loop
        for loc in (select to_number(column_value) as nlocationno from xmltable(rec.vlocationnno)) loop
          insert into tr_modulelocationdtl (nmoduleno, nlocationno)
          values (rec.nmoduleno, loc.nlocationno);
        end loop;
      end loop;
      delete from tr_testmodule;
      commit;
    end;
    

    【讨论】:

    • 由于我必须将其转换为 sql server 代码,我会在空闲时间完成,如果有任何查询,请告诉您。
    【解决方案3】:
    insert into TR_Modulelocationdtl (nmoduleno,nlocationno,vlocationcode,dmodifyon)(
    
    SELECT  nmoduleno, nlocal,PlaceMst.vCityCode,GETDATE()
    FROM    tr_modulemst
            CROSS APPLY ( SELECT    Split.a.value('.', 'VARCHAR(100)') AS nlocal
                          FROM      ( SELECT    CAST ('<M>' + REPLACE(vlocationno, ',','</M><M>')
                                                      + '</M>' AS XML) AS vlocationno) AS A
                          CROSS APPLY vlocationno.nodes('/M') AS Split ( a )
                        ) ca 
    
                        left join PlaceMst
                        on PlaceMst.nCityNo = nlocal
                        )
    

    【讨论】:

      猜你喜欢
      • 2013-10-08
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      • 1970-01-01
      • 2013-10-08
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多