Int*_*ble 3 sql-server concat sql-server-2014
在使用CONCAT
用户定义的表类型时,我遇到了在我看来是一个奇怪的排序问题。
我已经把 SQL 放在下面,让我可以重现这个:
我有以下用户类型:
CREATE TYPE [dbo].[StringList] AS TABLE
(
[Value] VARCHAR(8000) NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
以及以下用于设置所有内容的查询:
DECLARE @ColumnNames AS TABLE([ColumnName] VARCHAR(MAX))
DECLARE @ValueTable AS [dbo].[StringList] --VariableLineA
--DECLARE @ValueTable AS TABLE([Value] VARCHAR(MAX)) --VariableLineB
INSERT INTO @ColumnNames([ColumnName])
VALUES
('Forename'),
('Surname')
INSERT INTO @ValueTable([Value])
VALUES
('Ellis'), ('Ali')
Run Code Online (Sandbox Code Playgroud)
这是我正在运行的查询:
SELECT CONCAT(STRING_AGG(CONCAT([ColumnName], ' - ', [sc].[Value]), ', '), ', ') -- QueryLineA
--CONCAT(STRING_AGG([ColumnName] + ' - ' + [sc].[Value], ', '), ', ') --QueryLineB
FROM @ValueTable AS [sc]
INNER JOIN @ColumnNames ON 1=1
Run Code Online (Sandbox Code Playgroud)
如果该VariableLineB
行被取消注释,并且该VariableLineA
行被注释掉,那么如果单独或一起运行,将为两个查询行返回以下字符串:
Forename - Ellis, Forename - Ali, Surname - Ellis, Surname - Ali,
如果该VariableLineA
行未注释且该VariableLineB
行被注释掉,则为 返回以下字符串QueryLineB
,如果一起运行,则从两个查询中返回以下字符串,但不是 单独运行QueryLineA
:
Forename - Ellis, Forename - Ali, Surname - Ellis, Surname - Ali,
单独QueryLineA
运行时,将返回以下字符串:
Forename - Ellis, Surname - Ellis, Forename - Ali, Surname - Ali,
为什么顺序变了?我在这里看到了什么,有什么办法可以防止这种情况发生?
在使用方面, 的值@ValueTable
将被传递到函数中,并且原始顺序(无论是什么)保持不变很重要。
顺序发生变化是因为交叉联接中涉及的表的顺序发生了变化。在一个计划中@ValueTable
是外部(驱动)表,在另一个计划中是@ColumnNames
外部表。
for each row in @ColumnNames
for each row in @ValueTable
concatenate the result
//produces Forename - Ellis, Forename - Ali, Surname - Ellis, Surname - Ali,
for each row in @ValueTable
for each row in @ColumnNames
concatenate the result
//produces "Forename - Ellis, Surname - Ellis, Forename - Ali, Surname - Ali,"
Run Code Online (Sandbox Code Playgroud)
除非在查询中指定,否则永远不会保证顺序,因此如果一致的顺序很重要,您应该添加一个稳定的 order by 子句,为定义中的两个表定义顺序STRING_AGG
。
SELECT CONCAT(STRING_AGG(CONCAT([ColumnName], ' - ', [sc].[Value]), ', ')
WITHIN GROUP (ORDER BY [ColumnName], [sc].[Value]) , ', ') -- QueryLineA
FROM @ValueTable AS [sc]
INNER JOIN @ColumnNames ON 1=1
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
293 次 |
最近记录: |