Har*_*mar 9 sql-server t-sql unpivot
In this code I am converting the subjects(columns) English , Hindi , Sanskrith , into rows
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @colsUnpivot
=stuff(
(select ',' + quotename (C.name)
from sys.columns c
where c.object_id = OBJECT_ID('dbo.result2')
for xml path(''), TYPE) .value('.', 'NVARCHAR(MAX)'),
1, 8, ''
);
print @colsunpivot
select @query
= 'select Name, Subject,Marks
from result2
unpivot
(
marks for subject in (' + @colsunpivot + ')) as tab'
exec sp_executesql @query;
Run Code Online (Sandbox Code Playgroud)
Please explain what does for xml path(''), TYPE) .value('.', 'NVARCHAR(MAX)') do here .
Dan*_*man 23
A common technique for aggregate string concatenation before SQL Server 2017 is using XML data type methods along with STUFF
to remove the extra delimiter. In SQL Server 2017 and later, STRING_AGG
makes this task much cleaner and easier. The STRING_AGG
equivalent:
select @colsUnpivot = STRING_AGG(quotename (C.name),',')
from sys.columns c
where c.object_id = OBJECT_ID('dbo.result2')
Run Code Online (Sandbox Code Playgroud)
The components of the XML expression technique for aggregate string concatenation are as follows.
This subquery will generate a result set with one row per column in the source table with a comma preceding each column name:
select ',' + quotename (C.name)
from sys.columns c
where c.object_id = OBJECT_ID('dbo.result2')
Run Code Online (Sandbox Code Playgroud)
Example result:
,[column1]
,[column2]
,[column3]
Run Code Online (Sandbox Code Playgroud)
Adding the FOR XML PATH(''), TYPE
converts these rows into a single strongly-typed XML text node with the concatenated rows, allowing XML methods like value
to be used on the type:
select ',' + quotename (C.name)
from sys.columns c
where c.object_id = OBJECT_ID('dbo.result2')
for xml path(''), TYPE
Run Code Online (Sandbox Code Playgroud)
Result (XML type):
,[column1],[column2],[column3]
Run Code Online (Sandbox Code Playgroud)
Invoking the method value('.', 'NVARCHAR(MAX)')
on that XML node converts the XML node to an nvarchar(MAX) string. The value
XML data type method takes an XQuery expression with '.'
representing the current node (only node here) and the second argument being the desired SQL data type to be returned.
SELECT
(select ',' + quotename (C.name)
from sys.columns c
where c.object_id = OBJECT_ID('dbo.result2')
for xml path(''), TYPE).value('.', 'NVARCHAR(MAX)')
Run Code Online (Sandbox Code Playgroud)
Result (nvarchar(MAX)):
,[column1],[column2],[column3]
Run Code Online (Sandbox Code Playgroud)
Finally, the STUFF function removes the extraneous leading delimiter from the string. There is an error in your original example; the length should be 1 instead of 8 so that only the comma is removed:
SELECT
STUFF((select ',' + quotename (C.name)
from sys.columns c
where c.object_id = OBJECT_ID('dbo.result2')
for xml path(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
Run Code Online (Sandbox Code Playgroud)
Final result (nvarchar(MAX)):
[column1],[column2],[column3]
Run Code Online (Sandbox Code Playgroud)
I sometimes see folks omit the , TYPE).value('.', 'NVARCHAR(MAX)')
when using this technique. The problem with that is that some characters must be escaped with XML entity references (e.g; quotes) so the resultant string will not be as expected in that case.
EDIT:
结合 Mister Magoo 的建议使用(./text())[1]
而不是仅仅.
作为节点规范,下面的查询将提高大型数据集的性能。
SELECT
STUFF((select ',' + quotename (C.name)
from sys.columns c
where c.object_id = OBJECT_ID('dbo.result2')
for xml path(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)'),1,1,'');
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
24315 次 |
最近记录: |