SQL Server:从同一张表和不同表中提取日期时,请使用其他方法代替并集

时间:2018-08-02 08:05:44

标签: sql sql-server sql-server-2008-r2

我使用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      

问题:是不使用unionunion all来获取数据的更好方法吗?

使用的DBMS是SQL Server 2008 R2,但我可以升级到SQL Server 2014或更高版本。

更新

原始表具有数百万行。每个选择都从表中读取数据。 每行都是唯一的,列具有数据。 (nullable = False) 我想要提高性能的方法,并且无法更改结果选择的结构。

2 个答案:

答案 0 :(得分:4)

您可以尝试将CROSS APPLYVALUES一起使用

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 |

sqlfiddle

答案 1 :(得分:2)

它称为UNPIVOT

foo

结果:

self.moo

如果所有输出行都将有所不同(从检查当前查询来看,我希望是真的),那么对当前查询的转换也将更快,更少干扰-使用{{1} },而不是foodeclare @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 被指定为删除重复项,如果您的输出包含很多行,这将占处理时间的很大一部分。