T-SQL 行列互換


對於一個簡單的表, 兩行兩列(行號暫且不算). 要對它進行行列互換, 怎么做?

先准備測試數據:

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    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM