對於一個簡單的表, 兩行兩列(行號暫且不算). 要對它進行行列互換, 怎么做?
先准備測試數據:
CREATE TABLE TempSum( n INT, gender VARCHAR(10), total INT ); INSERT INTO TempSum(n, gender, total) VALUES (1, 'male', 23), (2, 'female', 45); SELECT * FROM TempSum;
n gender total ---- ------ ----- 1 male 23 2 female 45
看到行列互換, 大家首先想到的大概是PIVOT:
SELECT n, male, female FROM TempSum pivot(max(total) FOR gender IN (male, female)) AS P; n male female ---- ---- ------ 1 23 NULL 2 NULL 45
或者, n列也可以去掉的:
SELECT -- n, --uncomment to show n max(CASE WHEN gender='male' THEN total END) AS male, max(CASE WHEN gender='female' THEN total END) AS female FROM TempSum GROUP BY n; male female ---- ------ 23 NULL NULL 45
如果, 我不想要NULL, 要顯示成
male female 23 45
的樣式. 或者, 如果TempSum表中根本沒有n列. 怎么辦?
思路:
Step1, 把male和female放到一行
Step2, 把23和45放到一行, 要注意它們和gender的對應順序
Step3, 把Step1和Step2的兩行作個UNION. OK!
實現:
Step1, gender可以認為是已知的, hard code就可以的:
SELECT 'male', 'female'
Step2, male和female的total本不在同一行, 可以做個自連接, 選出來一行讓它左邊對應male的total, 右邊對應female的total:
SELECT convert(VARCHAR(10), a.total), convert(VARCHAR(10), b.total) FROM TempSum a JOIN TempSum b ON a.gender<>b.gender WHERE a.gender='male' --AND b.gender='female'
Step3, 用UNION ALL就可以的, 就不多解釋了:
SELECT 'male', 'female' UNION ALL SELECT convert(VARCHAR(10), a.total), convert(VARCHAR(10), b.total) FROM TempSum a JOIN TempSum b ON a.gender<>b.gender WHERE a.gender='male' --AND b.gender='female'; -- results No Column Name No Column Name -------------- -------------- male female 23 45
看到No Column Name, 把它也去掉吧. 其實, 走到Step2的時候, 大概就可以想到了:
SELECT convert(VARCHAR(10), a.total) AS male, convert(VARCHAR(10), b.total) AS female FROM TempSum a JOIN TempSum b ON a.gender<>b.gender WHERE a.gender='male' -- results male female ---- ------ 23 45
到這里, 我們已經拋棄了最初提到的n列, 屏蔽了NULL. 我們可以把列名gender、total加回來:
SELECT 'total' AS gender, convert(VARCHAR(10), a.total) AS male, convert(VARCHAR(10), b.total) AS female FROM TempSum a JOIN TempSum b ON a.gender<>b.gender WHERE a.gender='male'
最終, 我們從
gender total ------ ----- male 23 female 45
得到了
gender male female ------ ---- ------ total 23 45