将一行拆分为三个单独的行

Posted

技术标签:

【中文标题】将一行拆分为三个单独的行【英文标题】:split a row into three separate rows 【发布时间】:2020-05-05 18:35:48 【问题描述】:

我需要将一个 sql 行拆分为 3 个单独的行,下面是该行:

Trim_Master_id  Batch_id    mobius_A_start_runtime  mobius_A_end_runtime    mobius_A_runtime    mobius_B_start_runtime  mobius_B_end_runtime    mobius_B_runtime    mobius_C_start_runtime  mobius_C_end_runtime    mobius_C_runtime    Mobius_A_Number_Used    Mobius_B_Number_Used    Mobius_C_Number_Used
2             BD190626-022             246                     250                  4                    92                        96                   4                      65                     69         4                             0                          0                       0

我希望有这样的输出,还添加一个设备 id(其中 A = 1, B = 2, C =3):

Batch_id    epuipment_id    mobius_A_start_runtime  mobius_A_end_runtime    mobius_A_runtime    Mobius_A_Number_Used
Batch_id    equipment_id    mobius_B_start_runtime  mobius_B_end_runtime    mobius_B_runtime    Mobius_B_Number_Used
Batch_id    equipment_id    mobius_C_start_runtime  mobius_C_end_runtime    mobius_C_runtime    Mobius_C_Number_Used

最好的方法是什么,我尝试过交叉应用,但我认为我没有正确使用它:

    CASE
        WHEN t.mobius_b_number_used IS NULL AND t.mobius_c_number_used IS NULL THEN 1
        WHEN t.mobius_a_number_used IS NULL AND t.mobius_c_number_used IS NULL THEN 2
        WHEN t.mobius_a_number_used IS NULL AND t.mobius_b_number_used IS NULL THEN 3
    END AS ColGrp, (Select p.id from [phases] p
                        where p.batch in 
                            (select id from [batches] b
                                where b.[name] = Batch_id) and p.[type] = 4) PhaseID,
            t.[createdOn],
            GETDATE(),
            x.[mobius_A_start_runtime], 
            x.[mobius_A_end_runtime], 
            x.[Mobius_A_Number_Used],
            x.[mobius_B_start_runtime], 
            x.[mobius_B_end_runtime], 
            x.[Mobius_B_Number_Used],
            x.[mobius_C_start_runtime], 
            x.[mobius_C_end_runtime], 
            x.[Mobius_C_Number_Used],
            (select l.id FROM labour l
                where l.phase in 
                (Select p.id from [phases] p
                    where  p.[type] = 4 and l.created_at = p.created_at and p.batch in 
                        (select id from [batches] b
                        where b.[name] = Batch_id))) Labour
    FROM [Trim_Master] t
  CROSS APPLY
  (
    VALUES
      (t.[mobius_A_start_runtime], t.[mobius_A_end_runtime], t.[Mobius_A_Number_Used], NULL, NULL, NULL, NULL, NULL, NULL),
      (NULL, NULL, NULL, t.[mobius_B_start_runtime], t.[mobius_B_end_runtime], t.[Mobius_B_Number_Used], NULL, NULL, NULL),
      (NULL, NULL, NULL, NULL, NULL, NULL, t.[mobius_C_start_runtime], t.[mobius_C_end_runtime], t.[Mobius_C_Number_Used])
  ) AS x ([mobius_A_start_runtime], [mobius_A_end_runtime], [Mobius_A_Number_Used], [mobius_B_start_runtime], [mobius_B_end_runtime], [Mobius_B_Number_Used], [mobius_C_start_runtime], [mobius_C_end_runtime], [Mobius_C_Number_Used])
ORDER BY
  t.[mobius_A_start_runtime], t.[mobius_A_end_runtime], t.[Mobius_A_Number_Used] ASC,
  x.[mobius_A_start_runtime], x.[mobius_A_end_runtime], x.[Mobius_A_Number_Used] DESC,
  x.[mobius_B_start_runtime], x.[mobius_B_end_runtime], x.[Mobius_B_Number_Used] DESC,
  x.[mobius_C_start_runtime], x.[mobius_C_end_runtime], x.[Mobius_C_Number_Used] DESC
;

【问题讨论】:

【参考方案1】:

您可以使用cross apply,如下:

select x.*
from mytable t
cross apply (values
    (Batch_id, 'A', mobius_A_start_runtime, mobius_A_end_runtime, mobius_A_runtime, Mobius_A_Number_Used),
    (Batch_id, 'B', mobius_B_start_runtime, mobius_B_end_runtime, mobius_B_runtime, Mobius_B_Number_Used),
    (Batch_id, 'C', mobius_C_start_runtime, mobius_C_end_runtime, mobius_C_runtime, Mobius_C_Number_Used)
) as x(Batch_id, equipment_id, mobius_start_runtime, mobius_end_runtime, mobius_runtime, Mobius_Number_Used)

Demo on DB Fiddle

批号 |设备ID | mobius_start_runtime | mobius_end_runtime | mobius_runtime | Mobius_Number_Used :----------- | :----------- | -------------------: | -----------------: | -------------: | -----------------: BD190626-022 |一个 | 246 | 250 | 4 | 0 BD190626-022 |乙| 92 | 96 | 4 | 0 BD190626-022 | C | 65 | 69 | 4 | 0

【讨论】:

以上是关于将一行拆分为三个单独的行的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Safari 将某些短语拆分为单独的行?

如何将单独列中冒号前后的单词拆分为sql中的行

将带有“+”分隔符的字符串拆分为单独的行并应用聚合

如何使用类型化数据集将多值列拆分为单独的行?

将数据框转换为另一个数据框,将复合字符串单元格拆分为单独的行[重复]

Pyspark:将多个数组列拆分为行