SQL Server:从同一个表和不同表中获取日期时使用其他东西而不是联合
Posted
技术标签:
【中文标题】SQL Server:从同一个表和不同表中获取日期时使用其他东西而不是联合【英文标题】:SQL Server : use other thing instead of union when date fetch from same table and different table 【发布时间】:2018-08-02 08:05:43 【问题描述】:我使用union
来组合表格中的选定数据。从同一个表中选择的所有数据但在每个select
中,查询选择了一些不同的列。
表架构:
EID name x1 x2 x3
--------|--------|--------|--------|--------
int string float float float
样本数据:
小样
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 或更高版本。
更新:
原始表有数百万行。每个选择从表中读取数据。 每行都是唯一的,列有数据。 (可为空=假) 我想要提高性能的方法,但我无法更改结果选择的结构。
【问题讨论】:
定义“更好”。您遇到了什么问题? @iamdave 查询很慢,因为表有数百万条记录,并且每次都减少了选择和读取数据。 (我假设每个name
的预期输出应该只有一个x1
行,x2
和x3
也是如此,而不是您当前显示的内容,因为这是您的查询当前将产生的结果)
【参考方案1】:
您可以尝试将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 |
sqlfiddle
【讨论】:
【参考方案2】:它叫UNPIVOT
:
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
结果:
EID name result title
----------- ------------- ---------------------- -----
110 Tom 2 x1
110 Tom 3 x2
110 Tom 5 x3
110 John 4 x1
110 John 3 x2
110 John 6 x3
110 Sam 1 x1
110 Sam 2 x2
110 Sam 3 x3
如果您的所有输出行都将不同(从检查当前查询来看,我希望这是正确的),那么对当前查询的转换也会更快,干扰更少 - 使用 UNION ALL
而不是比UNION
。 UNION
被指定为删除重复项,如果您的输出包含大量行,这可能会占处理时间的很大一部分。
【讨论】:
表有 20 列,所有列都有数据。每条记录都是唯一的union all
是否优于 cross apply
或 unpivot
?
@AmirAbdollahi- 如果您想对现有查询进行最小的更改,我只会建议 union all
。如果UNPIVOT
对您正常工作(暂时忽略性能),我建议您这样做,因为语义,这就是您正在做的事情。所以告诉服务器你想要什么,然后它会尽力做到最好。如果UNPIVOT
表现不佳,是时候检查执行计划,看看是否缺少索引等。以上是关于SQL Server:从同一个表和不同表中获取日期时使用其他东西而不是联合的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 从当前日期计算天数,不包括另一个表中的天数
SQL从日期范围内的同一表中的不同记录中获取多个项目的总和(ORACLE)