Structured Query Language Solutions
This technique shuffles non-zero columns to the left. It is illustrated with teams where one or more players drop out. In the following table individuals are identified by their employee number with zeros indicating a player has droped out.
Name Captain Player1 Player2 Reserve blue 2003 2008 2112 2128 green 0 0 3113 0 red 1001 0 1035 1055 yellow 4041 4007 0 4112
The technique uses the SIGN function to count the values in each column, and if necessary the COALESCE function to shuffle values to the left. The COALESCE only works as required if zeros are translated to NULLs using the NULLIF function.
SELECT name, CASE WHEN SIGN(captain) = 1 THEN captain WHEN SIGN(captain) + SIGN(player1) + SIGN(player2) + SIGN(reserve) = 0 THEN 0 ELSE COALESCE(NULLIF(player1, 0), NULLIF(player2, 0), reserve ) END AS new_captain, CASE WHEN SIGN(captain) + SIGN(player1) = 2 THEN player1 WHEN SIGN(captain) + SIGN(player1) + SIGN(player2) + SIGN(reserve) < 2 THEN 0 ELSE COALESCE(NULLIF(player2, 0), reserve, 0) END AS new_PL1, CASE WHEN SIGN(captain) + SIGN(player1) + SIGN(player2) = 3 THEN player2 WHEN SIGN(captain) + SIGN(player1) + SIGN(player2) + SIGN(reserve) < 3 THEN 0 ELSE COALESCE(reserve, 0) END AS new_PL2, CASE WHEN SIGN(captain) + SIGN(player1) + SIGN(player2) + SIGN(reserve) = 4 THEN reserve ELSE 0 END AS new_reserve FROM teams ORDER BY 1 Name Captain Player1 Player2 Reserve blue 2003 2008 2112 2128 green 3113 0 0 0 red 1001 1035 1055 0 yellow 4041 4007 4112 0
How the Case Statements Work: Here we discuss the first CASE statement, which generates new_captain. The first condition checks the SIGN of column captain. If the value for captain isn’t zero, then its SIGN equals 1 and the captain value is returned. This is what happens for blue, red and yellow. However, the green’s value is 0, giving it a SIGN of 0, so this row fails the first condition and passes on to the second.
The second condition adds the SIGNs for all columns. The total is zero if all columns contain 0, and 0 is returned. Green fails this as well, so the ELSE condition applies.
In the ELSE condition, any Player1 or Player2 that equals 0 is replaced by NULL, but any other value is retained. COALESCE is then applied to the resulting value, which is returned. The Player2 value for green is replaced by NULL, but the Player3 value of 3113 is retained and is coalesced to the new_captain value.
Note that at this point green Player3 is still 3113. It isn’t until the last case statement, which results in new_reserve, that this gets “overwritten” with zero.