【问题标题】:SQL Substring issue in PIVOT statementPIVOT 语句中的 SQL 子字符串问题
【发布时间】:2016-02-29 14:36:18
【问题描述】:

我有一个非常大的表(100 多个字段),我需要在其中比较两条记录。为此,我决定使用 PIVOT。记录将由用户选择(因此它们将是动态的),但现在我将它们作为静态放入。

我的 SQL 如下所示:

-- Where clause params
DECLARE @whereClauseParam VARCHAR(MAX) = '[42] <> [600]' --<-- User will need to determine what the condition will be

--Get the Fields required for the initial pivot
DECLARE @Fields VARCHAR(MAX)= '';

SELECT @Fields+=QUOTENAME(t.name)+', '
FROM sys.columns AS t
WHERE t.object_id = OBJECT_ID('tblSQLAdminInventory')
    AND t.name <> 'TransID'
    AND t.system_type_id = '60';
--36
--48
--52
--56
--60
--61
--62
--104
--106
--127
--165
--167
--231
--239


-- Get the KeyId's with alias added
DECLARE @keyIDs VARCHAR(MAX)= '';

SELECT @keyIDs+=QUOTENAME(t.TransID)+' AS [KeyID_'+CAST(t.TransID AS VARCHAR(10))+'], '
FROM tblSQLAdminInventory AS t
WHERE TransID IN ('42', '600');

-- Get the KeyId's without alias
DECLARE @keyIDs1 VARCHAR(MAX)= '';

SELECT @keyIDs1+=QUOTENAME(t.TransID)+', '
FROM tblSQLAdminInventory AS t
WHERE TransID IN ('42', '600');

--Generate Dynamic SQL
DECLARE @SQL2 VARCHAR(MAX)= 'SELECT Value AS FieldName, ';

PRINT @SQL2+SUBSTRING(@keyIDs, 1, LEN(@keyIDs)-1)
PRINT @keyIDs
PRINT LEN(@keyIDs)

SELECT @SQL2+=SUBSTRING(@keyIDs, 1, LEN(@keyIDs)-1)+'
FROM
(SELECT TransID , Value , FieldName
FROM 
   (SELECT TransID,'+SUBSTRING(@Fields, 1, LEN(@Fields)-1)+'
   FROM tblSQLAdminInventory) p
UNPIVOT
   (FieldName  FOR Value IN 
      ('+SUBSTRING(@Fields, 1, LEN(@Fields)-1)+')
)AS unpvt) AS SourceTable
PIVOT
(
MAX(FieldName)
FOR TransID IN ('+SUBSTRING(@keyIDs1, 1, LEN(@keyIDs1)-1)+')
) AS PivotTable
--WHERE '+@whereClauseParam

PRINT(@SQL2);
EXECUTE(@SQL2);

我的 PIVOT 上方的 3 个 PRINT 行打印如下:

SELECT Value AS FieldName, [42] AS [KeyID_42], [600] AS [KeyID_600]
[42] AS [KeyID_42], [600] AS [KeyID_600], 
41

一切看起来都很好。但是,我的 PIVOT 上有一个错误:

Msg 537, Level 16, State 5, Line 49
Invalid length parameter passed to the LEFT or SUBSTRING function.
SELECT Value AS FieldName, 
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.

谁能告诉我为什么我的 PRINT 语句可以识别所有 3 个字段名称,但我的 PIVOT 语句不能?

奖励问题:当我过滤 t.system_type_id = '56' 时,它会返回数据。对于任何其他 system_type_id,我都会收到错误消息,并且没有返回任何记录。

编辑

根据要求,这是运行时没有错误的 SQL2:

SELECT Value AS FieldName, [42] AS [KeyID_42], [600] AS [KeyID_600]
FROM
(SELECT TransID , Value , FieldName
FROM 
   (SELECT TransID,[ErisaPlanEndsMM], [ErisaPlanEndsDD], [MLRAvgLivesNumber], [MLRAvgLivesRptYear]
   FROM tblSQLAdminInventory) p
UNPIVOT
   (FieldName  FOR Value IN 
      ([ErisaPlanEndsMM], [ErisaPlanEndsDD], [MLRAvgLivesNumber], [MLRAvgLivesRptYear])
)AS unpvt) AS SourceTable
PIVOT
(
MAX(FieldName)
FOR TransID IN ([42], [600])
) AS PivotTable
--WHERE [42] <> [600]

【问题讨论】:

  • 可以添加打印@SQL2的结果吗?
  • 我决定尝试通过 system_type_id 将其分开,因为我不断收到字段不是相同数据类型的错误。不确定我的攻击方式是否正确,但这是我能想到的。

标签: sql sql-server substring pivot


【解决方案1】:

不确定这是否能解决您的所有问题,但您可以使用它来构建您的 @keyIds 并消除对 Substring() 的需要

-- Get the KeyId's with alias added
DECLARE @keyIDs VARCHAR(MAX),       
        @keyIDs1 VARCHAR(MAX);

SELECT  @keyIDs = COALESCE(@keyIDs + ',','') + QUOTENAME(t.TransID) + ' AS [KeyID_' + CAST(t.TransID AS VARCHAR(10)) + ']',
        @keyIDs1 = COALESCE(@keyIDs1 + ',','') + QUOTENAME(t.TransID)
FROM    tblSQLAdminInventory AS t
WHERE   TransID IN ('42', '600');

【讨论】:

  • 这修复了其中两个。 :o) 还有一个问题,我将在另一个问题中解决。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
  • 2020-11-06
  • 2017-02-08
相关资源
最近更新 更多