【问题标题】:Rewriting SQL Server query with multiple UNIONs使用多个 UNION 重写 SQL Server 查询
【发布时间】:2012-12-17 20:19:23
【问题描述】:

有没有更好(更有效)的方式来编写这个查询?似乎应该有一种方法可以只用一个UNION 来编写它。

查询:

SELECT 'Value1' as PropertyKey, PropertyValue=(SELECT Value1 FROM MyTable WITH (NOLOCK))
UNION
SELECT 'Value2' as PropertyKey, PropertyValue=(SELECT Value2 FROM MyTable WITH (NOLOCK))
UNION
SELECT 'Value3' as PropertyKey, PropertyValue=(SELECT Value3 FROM MyTable WITH (NOLOCK))
UNION
...
SELECT 'Value100' as PropertyKey, PropertyValue=(SELECT Value100 FROM MyTable WITH (NOLOCK))

最终,我需要我的结果集有 2 列(PropertyKeyPropertyValue)。 PropertyKey 列中的值将是我的表中列的名称,PropertyValue 列中的值将是相应的值。

如果我总是从同一张表中选择,是否可以只用一个UNION 来写这个?

【问题讨论】:

    标签: sql sql-server union unpivot


    【解决方案1】:

    如果您可以访问UNPIVOT 函数,您可以通过以下方式使用它:

    select PropertyKey, PropertyValue
    from yourtable
    unpivot
    (
      PropertyValue
      for PropertyKey in (Value1, Value2, Value3) -- list other columns here
    ) unpiv
    

    UNPIVOT 要记住的关键是数据类型必须相同,因此您可能需要转换数据类型:

    select PropertyKey, PropertyValue
    from
    (
        select CAST(value1 as varchar(10)), 
             CAST(value1 as varchar(10)), ...
        from yourtable
    ) src
    unpivot
    (
      PropertyValue
      for PropertyKey in (Value1, Value2, Value3) -- list other columns here
    ) unpiv
    

    您甚至可以动态执行此操作,这将在运行时获取要转换的列列表:

    DECLARE @colsUnpivot AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)    
    
    select @colsUnpivot = stuff((select ','+quotename(C.name)
             from sys.columns as C
             where C.object_id = object_id('yourtable')
             for xml path('')), 1, 1, '')
    
    set @query 
      = 'select PropertyKey, PropertyValue
         from yourtable
         unpivot
         (
            PropertyValue
            for PropertyKey in ('+ @colsunpivot +')
         ) u'
    
    exec(@query)
    

    如果您卡住了,使用您当前的版本,那么我会稍微改变它并使用UNION ALL 而不是UNION

    SELECT 'Value1' as PropertyKey, Value1 PropertyValue
    FROM MyTable
    UNION ALL
    SELECT 'Value2' as PropertyKey, Value2 PropertyValue
    FROM MyTable
    

    【讨论】:

    • 感谢您的回复!如果我没有名为 PropertyKey 和 PropertyValue 的列,那么 unpivot 示例是否有效?这些不是我的实际列名,但我需要以这种方式返回它们。例如,我的结果集将包含一个名为 PropertyKey 的列,其中的所有记录都将我的实际列名作为 PropertyKey 列中的值返回。希望这是有道理的。
    • @lhan16 PropertyKey 将显示列的名称,PropertyValue 将具有每列的值。
    • 谢谢。我收到的错误是“列 'Value1' 的类型与 UNPIVOT 列表中指定的其他列的类型冲突。”如果我的列类型不同,我需要做任何类型的转换吗?
    • @lhan16 是的,数据类型必须相同才能执行 unpivot,请参阅我的编辑
    猜你喜欢
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多