Mary is a teacher in a middle school and she has a table seat
storing students' names and their corresponding seat ids.
+---------+---------+ | id | student | +---------+---------+ | 1 | Abbot | | 2 | Doris | | 3 | Emerson | | 4 | Green | | 5 | Jeames | +---------+---------+For the sample input, the output is:
+---------+---------+ | id | student | +---------+---------+ | 1 | Doris | | 2 | Abbot | | 3 | Green | | 4 | Emerson | | 5 | Jeames | +---------+---------+
Note:
If the number of students is odd, there is no need to change the last one's seat.
CASE
[Accepted]Algorithm
\nFor students with odd id, the new id is (id+1) after switch unless it is the last seat. And for students with even id, the new id is (id-1). In order to know how many seats in total, we can use a subquery:
\nSELECT\n COUNT(*) AS counts\nFROM\n seat\n
Then, we can use the CASE
statement and MOD()
function to alter the seat id of each student.
MySQL
\nSELECT\n (CASE\n WHEN MOD(id, 2) != 0 AND counts != id THEN id + 1\n WHEN MOD(id, 2) != 0 AND counts = id THEN id\n ELSE id - 1\n END) AS id,\n student\nFROM\n seat,\n (SELECT\n COUNT(*) AS counts\n FROM\n seat) AS seat_counts\nORDER BY id ASC;\n
COALESCE()
[Accepted]Algorithm
\nBit manipulation expression (id+1)^1-1
can calculate the new id after switch.
SELECT id, (id+1)^1-1, student FROM seat;\n
| id | (id+1)^1-1 | student |\n|----|------------|---------|\n| 1 | 2 | Abbot |\n| 2 | 1 | Doris |\n| 3 | 4 | Emerson |\n| 4 | 3 | Green |\n| 5 | 6 | Jeames |\n
Then, we can make a temp table and join seat with this table like below.
\nSELECT\n *\nFROM\n seat s1\n LEFT JOIN\n seat s2 ON (s1.id+1)^1-1 = s2.id\nORDER BY s1.id;\n
| id | student | id | student |\n|----|---------|----|---------|\n| 1 | Abbot | 2 | Doris |\n| 2 | Doris | 1 | Abbot |\n| 3 | Emerson | 4 | Green |\n| 4 | Green | 3 | Emerson |\n| 5 | Jeames | | |\n
\n\nNote:The first two columns are from s1 and the last two are from s2.
\n
At last, we can output s1.id and s2.student. However, the s2.student is NULL for seat id \'5\' but s1.student is right. Thus, we we can use function COALESCE()
to generate the correct output for the last record.
MySQL
\nSELECT\n s1.id, COALESCE(s2.student, s1.student) AS student\nFROM\n seat s1\n LEFT JOIN\n seat s2 ON ((s1.id + 1) ^ 1) - 1 = s2.id\nORDER BY s1.id;\n
\n\nNote: This solution comes from @FANGXIAOFANG.
\n