Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Reduzieren einer 1-Zeilen-Tabelle in eine Schlüssel-Wert-Paar-Tabelle

Eine Version, bei der es keine Dynamik gibt. Wenn Sie Spaltennamen haben, die für die Verwendung als Elementnamen in XML ungültig sind, schlägt dies fehl.

select T2.N.value('local-name(.)', 'nvarchar(128)') as [Key],
       T2.N.value('text()[1]', 'nvarchar(max)') as Value
from (select *
      from TableA
      for xml path(''), type) as T1(X)
  cross apply T1.X.nodes('/*') as T2(N)

Ein funktionierendes Beispiel:

declare @T table
(
  Column1 varchar(10), 
  Column2 varchar(10), 
  Column3 varchar(10)
)

insert into @T values('V1','V2','V3')

select T2.N.value('local-name(.)', 'nvarchar(128)') as [Key],
       T2.N.value('text()[1]', 'nvarchar(max)') as Value
from (select *
      from @T
      for xml path(''), type) as T1(X)
  cross apply T1.X.nodes('/*') as T2(N)

Ergebnis:

Key                  Value
-------------------- -----
Column1              V1
Column2              V2
Column3              V3

Aktualisieren

Für eine Abfrage mit mehr als einer Tabelle könnten Sie for xml auto verwenden um die Tabellennamen im XML zu erhalten. Beachten Sie, wenn Sie Alias ​​für Tabellennamen in der Abfrage verwenden, erhalten Sie stattdessen den Alias.

select X2.N.value('local-name(..)', 'nvarchar(128)') as TableName,
       X2.N.value('local-name(.)', 'nvarchar(128)') as [Key],
       X2.N.value('text()[1]', 'nvarchar(max)') as Value
from (
     -- Your query starts here
     select T1.T1ID,
            T1.T1Col,
            T2.T2ID,
            T2.T2Col
     from T1
       inner join T2
         on T1.T1ID = T2.T1ID
     -- Your query ends here
     for xml auto, elements, type     
     ) as X1(X)
  cross apply X1.X.nodes('//*[text()]') as X2(N)

SQL-Geige