在数据透视查询中从多个值列中选择一个值列

问题描述 投票:0回答:1

我在 SQL Server 中有一个表,其中的行如下:

ID(整数) 名称(varchar) 已启用(int) 对象名称(varchar) 属性名称(varchar) 属性值字符串(varchar) PropertyValueInt
1 规则01 1 我的对象
2 规则02 1 我的对象
3 规则03 1 我的对象
4 规则04 1 我的对象
5 规则05 1 我的对象
6 提案01 0 我的对象 提案01 $
7 提案02 0 我的对象 提案02 45

我编写了这个存储过程,它根据传入的

ObjectName
参数动态地将行旋转为列:

DECLARE @cols  AS NVARCHAR(MAX)='';
DECLARE @query AS NVARCHAR(MAX)='';

SELECT 
    @cols = @cols + QUOTENAME(Name) + ',' 
FROM 
    (SELECT DISTINCT Name 
     FROM ItemsTable 
     WHERE LOWER(ObjectName) = LOWER(@objectName)  
     GROUP BY Name) AS tmp

SELECT @cols = SUBSTRING(@cols, 0, LEN(@cols))

SET @query = 
'SELECT * FROM 
(
    SELECT  
      [Name]      
      ,CAST([IsEnabled] AS VARCHAR(50)) as [ValueColumn]  
      ,[ObjectName]           
      FROM ItemsTable 
    UNION
        SELECT  
      [Name]      
      ,[PropertyValueString]    as [ValueColumn]  
      ,[ObjectName]           
      FROM ItemsTable 
    UNION
        SELECT  
      [Name]      
      ,CAST([PropertyValueInt] AS VARCHAR(50))  as [ValueColumn]  
      ,[ObjectName]           
      FROM ItemsTable 
) src
pivot 
(
    max(ValueColumn) for Name in (' + @cols + ')
) piv'

返回的值之一不正确,特别是对于

Prop01
。我期待返回“$”,但得到的是
0

如何修复此错误?

sql sql-server pivot dynamic-sql
1个回答
0
投票

嗯,字符

'0'
的排序高于
'$'
,因此
'0'
对于给定的逻辑是正确的。如果您想将
IsEnabled = 0
视为微不足道,也许您希望在联合的第一部分中使用
NULLIF([IsEnabled], 0)
。您的
PropertyValueInt
专栏可能需要类似的内容。

或者您希望 id 将零视为空字符串(而不是 null),您可以尝试

ISNULL(CAST(NULLIF([IsEnabled], 0) AS VARCHAR(50)), '''')
(动态 SQL 字符串的引号加倍)。

另一种方法是删除

UNION
并使用
CROSS APPLY
为每行选择适当的源值。

SET @query = 
'SELECT * FROM 
(
    SELECT  
        I.Name
        ,V.ValueColumn
        ,I.ObjectName
    FROM ItemsTable I
    CROSS APPLY (
        SELECT COALESCE(
            I.PropertyValueString,
            CAST(I.PropertyValueInt AS VARCHAR(50)),
            CAST(I.IsEnabled AS VARCHAR(50))
            ) AS ValueColumn
    ) V
) src
pivot
(
    max(ValueColumn) for Name in (' + @cols + ')
) piv'

这假设每行不超过一个

PropertyValue*
列为非空,并且
IsEnabled
仅在所有属性值为空时适用。您可以根据需要进一步调整逻辑。

看到这个db<>小提琴

© www.soinside.com 2019 - 2024. All rights reserved.