I'd like to return multiple values from the same record, with different columns of the same type appended under one another. I could do multiple joins, but that seems very inefficient because of the multiple table scans.
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
Returns:
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 |
This is exactly what I'm looking for, but it's painfully slow. Is there a better way?
CodePudding user response:
You need to unpivot each row. This means that you only scan the table once, then break it out into separate rows. You could use UNPIVOT
, but CROSS APPLY (VALUES
is far more flexible.
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;
It goes without saying that your table is seriously denormalized and should be redesigned pronto.