我使用union
合并表中的选定数据。从同一表中选择的所有数据,但在每个select
中,查询选择了一些不同的列。
表架构:
EID name x1 x2 x3
--------|--------|--------|--------|--------
int string float float float
样本数据:
Sampletbl
EID name x1 x2 x3
------|------|------|------|------
110 Tom 2 3 5
110 John 4 3 6
110 Sam 1 2 3
查询:
select
name, 'x1' as title, x1 as result
from
Sampletbl
where
EID = 110
union
select
name, 'x2' as title, x2 as result
from
Sampletbl
where
EID = 110
union
select
name, 'x3' as title, x3 as result
from
Sampletbl
where
EID = 110
输出结果应如下所示:
name title result
------|-------|------
Tom x1 2
Tom x1 3
Tom x1 5
John x2 4
John x2 4
John x2 6
Sam x3 1
Sam x3 2
Sam x3 3
问题:是不使用union
或union all
来获取数据的更好方法吗?
使用的DBMS是SQL Server 2008 R2,但我可以升级到SQL Server 2014或更高版本。
更新:
原始表具有数百万行。每个选择都从表中读取数据。 每行都是唯一的,列具有数据。 (nullable = False) 我想要提高性能的方法,并且无法更改结果选择的结构。
答案 0 :(得分:4)
您可以尝试将CROSS APPLY
与VALUES
一起使用
SELECT v.*
FROM T
CROSS APPLY (VALUES (name, 'x1',x1),
(name, 'x2',x2),
(name, 'x3',x3)
)
v (name, title,result )
order by title
[结果] :
| name | title | result |
|-------|-------|--------|
| Tom | x1 | 2 |
| John | x1 | 4 |
| Sam | x1 | 1 |
| Sam | x2 | 2 |
| John | x2 | 3 |
| Tom | x2 | 3 |
| Tom | x3 | 5 |
| John | x3 | 6 |
| Sam | x3 | 3 |
答案 1 :(得分:2)
它称为UNPIVOT
:
foo
结果:
self.moo
如果所有输出行都将有所不同(从检查当前查询来看,我希望是真的),那么对当前查询的转换也将更快,更少干扰-使用{{1} },而不是foo
。 declare @t table (EID int, name varchar(13), x1 float, x2 float, x3 float)
insert into @t(EID,name,x1,x2,x3) values
(110,'Tom ',2,3,5),
(110,'John',4,3,6),
(110,'Sam ',1,2,3)
select
*
from
@t
unpivot (
result for title in (x1,x2,x3)) u
被指定为删除重复项,如果您的输出包含很多行,这将占处理时间的很大一部分。