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?
Advertisement
Answer
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.