使用多个 UNION 重写 SQL Server 查询
Posted
技术标签:
【中文标题】使用多个 UNION 重写 SQL Server 查询【英文标题】:Rewriting SQL Server query with multiple UNIONs 【发布时间】: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 列(PropertyKey
和 PropertyValue
)。 PropertyKey
列中的值将是我的表中列的名称,PropertyValue
列中的值将是相应的值。
如果我总是从同一张表中选择,是否可以只用一个UNION
来写这个?
【问题讨论】:
【参考方案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 列中的值返回。希望这是有道理的。 @lhan16PropertyKey
将显示列的名称,PropertyValue
将具有每列的值。
谢谢。我收到的错误是“列 'Value1' 的类型与 UNPIVOT 列表中指定的其他列的类型冲突。”如果我的列类型不同,我需要做任何类型的转换吗?
@lhan16 是的,数据类型必须相同才能执行 unpivot,请参阅我的编辑以上是关于使用多个 UNION 重写 SQL Server 查询的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server-聚焦UNIOL ALL/UNION查询