2016-07-01 40 views
0

我們有如下表(測試2)在MySQL數據庫(MySQL的5.6):MySQL的 - 行分列並保持空

TEAM_ID,MEMBER_ID,TYPE,SCORE 
1,2,A,150 
1,3,B,200 
1,1,B,50 
1,1,A,100 
1,2,B,NULL 

我們試着變換/旋轉基於該類型的列上表:

如果TYPE列的值爲== A,則將SCORE列中的值移動到名爲A_SCORE的新列中。如果SCORE列中的值爲NULL,則應在新的A_SCORE列中顯示NULL。

如果TYPE列的值爲== B,則將SCORE列中的值移動到名爲B_SCORE的新列中。如果SCORE列中的值爲NULL,則應在新的B_SCORE列中顯示NULL。

下表是我們正在尋找的(想要的表)的一個:我們嘗試下面的查詢

SELECT TEAM_ID,MEMBER_ID,A_SCORE,B_SCORE,SUM(A_SCORE-B_SCORE) AS ACTUAL_MINUS_B_SCORE FROM 
    (SELECT TEAM_ID,MEMBER_ID, 

CASE 
WHEN SCORE IS NULL 
THEN NULL 
ELSE SUM(if(TYPE = 'A', SCORE,0)) 
END A_SCORE, 

CASE 
WHEN SCORE IS NULL 
THEN NULL 
ELSE SUM(if(TYPE = 'B', SCORE,0)) 
END B_SCORE 
FROM TEST2 
GROUP BY TEAM_ID,MEMBER_ID,SCORE) AS A 
GROUP BY TEAM_ID,MEMBER_ID,A_SCORE,B_SCORE); 

TEAM_ID,MEMBER_ID,A_SCORE,B_SCORE,A_SCORE_MINUS_B_SCORE 
1,1,100,50,50 
1,2,150,NULL,NULL 
1,3,0,200,-200 

它返回的東西我們不想:

TEAM_ID,MEMBER_ID,A_SCORE,B_SCORE,A_SCORE_MINUS_B_SCORE 
1,1,0,50,-50 
1,1,100,0,100 
1,2,0,0,0 
1,2,150,0,150 
1,3,0,200,-200 

如果我們嘗試以下操作,它會生成一個與我們想要的相近的表,但它不會返回n任何NULL值。

SELECT TEAM_ID,MEMBER_ID,A_SCORE,B_SCORE,SUM(A_SCORE-B_SCORE) AS A_SCORE _MINUS_B_SCORE FROM 
    (SELECT TEAM_ID,MEMBER_ID, 

SUM(if(TYPE = 'A', SCORE,0)) AS A_SCORE, 

SUM(if(TYPE = 'B', SCORE,0))AS B_SCORE 
FROM TEST2 
GROUP BY TEAM_ID,MEMBER_ID) AS A 
GROUP BY TEAM_ID,MEMBER_ID,A_SCORE,B_SCORE; 

上述查詢的結果:

TEAM_ID,MEMBER_ID,A_SCORE,B_SCORE,A_SCORE_MINUS_B_SCORE 
1,1,100,50,50 
1,2,150,0,0 
1,3,0,200,-200 

可以在任何大師指教如何生成在這種情況下使用MySQL想要的表? SQL小提琴在這裏是爲了您的方便。

http://sqlfiddle.com/#!9/cfe7a1/1

謝謝!

+0

是否有Sqlfiddle? – Strawberry

+0

http://sqlfiddle.com/#!9/cfe7a1/1 – Chubaka

+0

在這裏,你走了。如上! – Chubaka

回答

1

試試這個;)

SELECT TEAM_ID, MEMBER_ID, A_SCORE, B_SCORE, A_SCORE - B_SCORE AS A_SCORE_MINUS_B_SCORE 
FROM (
    SELECT 
     TEAM_ID, MEMBER_ID, 
     CASE 
      WHEN A_SCORE IS NULL AND NOT EXISTS (
       SELECT 1 FROM TEST2 
       WHERE TEAM_ID = T1.TEAM_ID 
       AND MEMBER_ID = T1.MEMBER_ID 
       AND TYPE = 'A' 
      ) THEN 0 ELSE A_SCORE END AS A_SCORE, 
     CASE 
      WHEN B_SCORE IS NULL AND NOT EXISTS (
       SELECT 1 FROM TEST2 
       WHERE TEAM_ID = T1.TEAM_ID 
       AND MEMBER_ID = T1.MEMBER_ID 
       AND TYPE = 'A' 
      ) THEN 0 ELSE B_SCORE END AS B_SCORE 
    FROM (
     SELECT 
      TEAM_ID, MEMBER_ID, 
      MAX(CASE WHEN TYPE = 'A' THEN SCORE END) AS A_SCORE, 
      MAX(CASE WHEN TYPE = 'B' THEN SCORE END) AS B_SCORE 
     FROM TEST2 
     GROUP BY TEAM_ID, MEMBER_ID 
    ) T1 
)T 

SQLFiddle demo here

+0

乍一看,這看起來像一個可怕的很多查詢 – Strawberry

+0

@Strawberry你說得對,似乎是可怕的,我甚至找不到另一種方式來實現這一點。你能給我一些提示嗎? – Blank

+0

謝謝!你的查詢給我啓發!我在這裏學到的核心是「MAX(CASE WHEN TYPE ='A'THEN SCORE END)A_SCORE」! – Chubaka

0

我不太明白的計算標準,但這樣的事情應該工作...

SELECT team_id 
    , member_id 
    , COALESCE(MAX(CASE WHEN type = 'A' THEN score END),0) a_score 
    , COALESCE(MAX(CASE WHEN type = 'B' THEN score END),0) b_score 
    , COALESCE(MAX(CASE WHEN type = 'A' THEN score END),0) 
    - COALESCE(MAX(CASE WHEN type = 'B' THEN score END),0) diff 
    FROM test2 
GROUP 
    BY team_id 
    , member_id;