SQL Server - отменить (двойное) или перекрестное применение для двойного удаления? - PullRequest
1 голос
/ 22 мая 2019

Я пытаюсь выяснить, как эффективно выполнить двойное разворачивание.

Я знаю Unpivot; он берет выбранные столбцы (Wizards, Apples, Bananas, Books) и объединяет их в два столбца, обычно это категориальный дескриптор и само значение - и этим двум новым столбцам нужны имена (Stuff_type, Stuff_count).

Иногда, хотя у вас есть коллекция столбцов и вы хотите отключить оба. Такие как

    apple_count, apple_weight, wizard_count, wizard_weight, book_count, book_weight
        1,           12.0,         2,           23.0,           3,        34.0

Есть ли эффективный способ отключить обе эти колонки? По сути, вы бы вернули следующее:

Item_Name, Item_Weight, Item_Count
apple         12.0          1
wizard        23.0          2

Требуется ли для этого два разворота, или есть более эффективный способ?

Будет ли применение кросса более элегантным?

1 Ответ

1 голос
/ 22 мая 2019

Вот опция, которая будет «динамически» удалять ваши данные без фактического использования динамического SQL.Здесь я использую вспомогательный TVF, но его легко конвертировать в CROSS APPLY

Пример

Select Item_Name   = left(Item,charindex('_',Item+'_')-1)
      ,Item_Weight = max(case  when Item like '%_weight' then convert(decimal(10,1),Value) end)
      ,Item_Count  = max(case  when Item like '%_count'  then convert(int,Value) end)
 From   YourTable A
 Cross Apply [dbo].[tvf-XML-UnPivot-Row]((Select A.* for XML Raw)) b
 Group By left(Item,charindex('_',Item+'_')-1)

Возвращает

Item_Name   Item_Weight Item_Count
apple       12.0        1
book        34.0        3
wizard      23.0        2

Функция при наличии интереса

CREATE FUNCTION [dbo].[tvf-XML-UnPivot-Row](@XML xml)
Returns Table 
As
Return ( 
        Select Item  = xAttr.value('local-name(.)', 'varchar(100)')
              ,Value = xAttr.value('.','varchar(max)')
         From  @XML.nodes('//@*') xNode(xAttr)
)

/*
Select A.ID
      ,B.*
 From  YourTable A
 Cross Apply [dbo].[tvf-XML-UnPivot-Row]((Select A.* for XML RAW)) B
*/
...