【问题标题】:How to "duplicate" a row in SQL Server?如何在 SQL Server 中“复制”一行?
【发布时间】:2021-04-25 23:17:50
【问题描述】:

我从 SQL Server 开始。我首先编写了一个创建表的查询。有了这张表,我想添加一些行。

下面的代码创建了表格。

select 
    Element = [Key],
    New = max(case when time_index=1 then value end),
    'Current' = max(case when time_index>=2 then value end)
from
    (select 
         [time_index], B.*
     from   
         (select * 
          from ifrs17.output_bba 
          where id in (602677, 602777)) A
     cross apply 
         (select [Key], Value
          from OpenJson((select A.* FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)) 
          where [Key] not in ('time_index')) B
    ) A
group by 
    [Key]

结果在这里

Element New Current
AAA 10 20
BBB 15 34
CCC 17 22

现在,我想(例如)复制第二行(“BBB”)并将名称(“Element”)更改为“DDD”。

Element New Current
AAA 10 20
BBB 15 34
CCC 17 22
DDD 15 34

您知道如何进行吗?

【问题讨论】:

标签: sql sql-server union


【解决方案1】:

不确定我是否完全理解,但可能是这样的:

with X as 
(
select Element = [Key]
    ,New = max(case when time_index=1 then value end)
    ,'Current' = max(case when time_index>=2 then value end)
From  (
    Select [time_index]
            ,B.*
        From  (select * from ifrs17.output_bba where id in (602677,602777)) A
        Cross Apply (
                    Select [Key]
                        ,Value
                    From OpenJson( (Select A.* For JSON Path,Without_Array_Wrapper ) ) 
                    Where [Key] not in ('time_index')
                    ) B
    ) A
Group By [Key]
)
select Element, New, [Current] from X 
union all
select 'DDD' as Element, New, [Current] from X where Element = 'BBB'

【讨论】:

  • 您可以 cross apply 那个 union all 并引用现有的外部查询行,而不是对 X 进行另一次索引扫描/搜索
  • 感谢@Charlieface!有用。如果我想添加几行怎么办?例如,重复元素 BBB(如示例中所示)和重复元素 CCC ?
  • @Charlieface:交叉应用于 X 不会导致两次表扫描吗?你是怎么写的?
  • 不,如果您使用外部引用而不是 from,则不会。我会自己给出答案编辑:查看我的答案
【解决方案2】:

引用 Johnny Fitz 的回答,您无需对 X 进行额外的表扫描,只需将 UNION ALL 放入 CROSS APPLY 中并在查询中引用其他部分即可:

with X as 
(
select Element = [Key]
    ,New = max(case when time_index=1 then value end)
    ,'Current' = max(case when time_index>=2 then value end)
From  (
    Select [time_index]
            ,B.*
        From  (select * from ifrs17.output_bba where id in (602677,602777)) A
        Cross Apply (
                    Select [Key]
                        ,Value
                    From OpenJson( (Select A.* For JSON Path,Without_Array_Wrapper ) ) 
                    Where [Key] not in ('time_index')
                    ) B
    ) A
Group By [Key]
)

select
    v.Element,
    X.New,
    X.[Current]
from X 
cross apply (
    select x.Element
    union all
    select 'DDD' as Element
    where X.Element = 'BBB'
) v

APPLY 在遇到BBB 时有条件地增加一行

【讨论】:

    【解决方案3】:

    一般来说,为了复制(或相乘)行,我使用 Left JOIN(或 INNER JOIN)到 VALUES

    SELECT * FROM MyTable   -- (id,value)
    LEFT JOIN (VALUES (1),(2),(3) )AS t(k)  ON 
    --what should be multiplicated and how
    (id IN (1,2,3) and k<=2)
    or id not in (1,2,3) and k<=3
    

    与 INNER join 一起工作,但至少需要加入 K 中的 1 行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-10
      • 1970-01-01
      • 2017-06-17
      • 2010-09-08
      相关资源
      最近更新 更多