有没有更有效的方法从同一个表中追加多个列?

Posted

技术标签:

【中文标题】有没有更有效的方法从同一个表中追加多个列?【英文标题】:Is there a more efficient way to append multiple columns from the same table? 【发布时间】:2021-12-31 00:25:20 【问题描述】:

我想从同一个记录中返回多个值,并将相同类型的不同列附加在另一个列下。我可以进行多个连接,但由于多次表扫描,这似乎非常低效。

declare @gameID as VarChar(30)
select @gameID = '20210829-SLNvsPIT-0'

select Vis1ID as VisID, Vis1 as Vis, Home1 as Home, Home1ID as HomeID
from Baseball.dbo.GameLogs
where GameID = @gameID
union
select Vis2ID, Vis2, Home2, Home2ID
from Baseball.dbo.GameLogs
where GameID = @gameID
union
.......
select Vis9ID, Vis9, Home9, Home9ID
from Baseball.dbo.GameLogs
where GameID = @gameID

返回:

VisID Vis Home HomeID
arenn001 Nolan Arenado Colin Moran morac001
badeh001 Harrison Bader Anthony Alford alfoa002
carld002 Dylan Carlson Yoshi Tsutsugo tsuty001
edmat001 Tommy Edman Kevin Newman newmk001
goldp001 Paul Goldschmidt Ke'Bryan Hayes hayek001
kim-k001 Kwang Kim Wil Crowe croww001
moliy001 Yadier Molina Jacob Stallings stalj001
oneit001 Tyler O'Neill Bryan Reynolds reynb001
sosae001 Edmundo Sosa Cole Tucker tuckc001

这正是我正在寻找的,但它非常缓慢。有没有更好的办法?

【问题讨论】:

它可能很慢,因为您使用的是UNION 而不是UNION ALL。联合当然是完成您正在做的事情的正确方法。当然,更好的桌子设计将是最好的解决方案。 【参考方案1】:

您需要取消透视每一行。这意味着您只需扫描表一次,然后将其分成单独的行。您可以使用UNPIVOT,但CROSS APPLY (VALUES 更灵活。

DECLARE @gameID varchar(30) = '20210829-SLNvsPIT-0';

SELECT
  v.VisID,
  v.Vis,
  v.Home,
  v.HomeID
FROM dbo.GameLogs gl
CROSS APPLY (VALUES
    (Vis1ID, Vis1, Home1, Home1ID),
    (Vis2ID, Vis2, Home2, Home2ID),
    (Vis3ID, Vis3, Home3, Home3ID),
    (Vis4ID, Vis4, Home4, Home4ID) -- .....
) v(VisID, Vis, Home, HomeID)
WHERE gl.GameID = @gameID;

不用说,您的表严重非规范化,应该立即重新设计。

【讨论】:

以上是关于有没有更有效的方法从同一个表中追加多个列?的主要内容,如果未能解决你的问题,请参考以下文章

从具有多个基表的视图中删除记录的最有效方法?

Pig:读取多个文件并逐列追加

Pandas 组合 BQ 表中的多个列以生成 FB 转换 api 的有效负载

使用 Oracle PLSQL 从动态选择的表中合并唯一值的更有效方法

Spark 从另一个表更新 Delta 中的多个列

从文件中存储记录的更有效方法