2013-02-08 54 views
0

對於下表,是否可以創建SQL語句來創建數據矩陣或視圖?SQL語句 - SQL Matrix

表:

TeamA|TeamB|Won|Lost 
-------------------- 
    A | B | 5 | 3 
    A | C | 2 | 4 
    A | D | 9 | 1 
    B | E | 5 | 5 
    C | A | 2 | 4 

結果矩陣:

 | A | B | C | D | E 
---------------------------- 
    A | 0 | 2 | -2 | 8 | 0 
    B | 0 | 0 | 0 | 0 | 0 
    C | -2 | 0 | 0 | 0 | 0 
+2

它不會是太難的事它的五支球隊的具體情況,但是這將擴展到任意數量的團隊和遊戲的一個通用的解決方案將是相當棘手單獨使用sql。 – paul 2013-02-08 12:48:32

+3

數據庫用於存放和獲取數據,**不**可以很好地格式化數據。這是在表示層完成的! – fancyPants 2013-02-08 12:59:49

+0

@Megachip。 。 。這兩個都是矩陣。他們只是代表不同。 – 2013-02-08 14:02:53

回答

1

有兩種方法,你可以在樞軸數據在MySQL中。如果您事先知道這些值(團隊),那麼您將對這些值進行硬編碼,或者您可以使用準備好的語句來生成動態SQL。

靜態版本是:

select TeamA, 
    max(case when TeamB = 'A' then won - lost else 0 end) as A, 
    max(case when TeamB = 'B' then won - lost else 0 end) as B, 
    max(case when TeamB = 'C' then won - lost else 0 end) as C, 
    max(case when TeamB = 'D' then won - lost else 0 end) as D, 
    max(case when TeamB = 'E' then won - lost else 0 end) as E 
from yourtable 
group by TeamA; 

SQL Fiddle with Demo

如果你想使用一個事先準備好的聲明動態版,代碼如下:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'MAX(CASE WHEN TeamB = ''', 
     TeamB, 
     ''' THEN won - lost else 0 END) AS `', 
     TeamB, '`' 
    ) 
) INTO @sql 
from 
(
    select * 
    from yourtable 
    order by teamb 
) x; 

SET @sql 
    = CONCAT('SELECT TeamA, ', @sql, ' 
      from yourtable 
      group by TeamA'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

SQL Fiddle with Demo

編輯#1,在想到這個後,我實際上會做這個稍微有點不同。我會在隊伍出現在行和列中的數據中生成一個真正的矩陣。要做到這一點,你會首先使用UNION ALL查詢來獲取所有的球隊在兩列:

select teama Team1, teamb Team2, 
    won-lost Total 
from yourtable 
union all 
select teamb, teama, 
    won-lost 
from yourtable 

SQL Fiddle with Demo。一旦做到這一點,那麼你會支點數據:

select Team1, 
    coalesce(max(case when Team2 = 'A' then Total end), 0) as A, 
    coalesce(max(case when Team2 = 'B' then Total end), 0) as B, 
    coalesce(max(case when Team2 = 'C' then Total end), 0) as C, 
    coalesce(max(case when Team2 = 'D' then Total end), 0) as D, 
    coalesce(max(case when Team2 = 'E' then Total end), 0) as E 
from 
(
    select teama Team1, teamb Team2, 
    won-lost Total 
    from yourtable 
    union all 
    select teamb, teama, 
    won-lost 
    from yourtable 
) src 
group by Team1; 

SQL Fiddle with Demo。它給出了更詳細的結果:

| TEAM1 | A | B | C | D | E | 
------------------------------- 
|  A | 0 | 2 | -2 | 8 | 0 | 
|  B | 2 | 0 | 0 | 0 | 0 | 
|  C | -2 | 0 | 0 | 0 | 0 | 
|  D | 8 | 0 | 0 | 0 | 0 | 
|  E | 0 | 0 | 0 | 0 | 0 | 
+0

迄今爲止工作,但如果團隊數字不是字符串,我會遇到麻煩...... – Megachip 2013-02-08 15:03:32

+0

@Megachip可以編輯sql提琴數據的樣本?然後將該鏈接發佈爲評論。 – Taryn 2013-02-08 15:04:58

+0

http://www.sqlfiddle.com/#!2/40bb3/2可能存在引用問題? – Megachip 2013-02-08 15:08:24

1

您不能創建具有可變數量的列的SQL語句或視圖。在標準SQL中,可以通過執行類似以下操作來轉發數據:

select TeamA, 
     max(case when TeamB = 'A' then won - lost end) as A, 
     max(case when TeamB = 'B' then won - lost end) as B, 
     max(case when TeamB = 'C' then won - lost end) as C, 
     max(case when TeamB = 'D' then won - lost end) as D, 
     max(case when TeamB = 'E' then won - lost end) as E 
from t 
group by TeamA 
order by 1 

某些數據庫支持一個pivot語句。

一般來說,您必須創建一個SQL語句作爲字符串,然後執行它(通常稱爲動態 SQL)。這樣的語句可以由SQL,存儲過程,Excel或其他編程工具生成。然後它需要被執行。

讓我重複一遍:任何給定的SQL語句都有一組預定義的列。你不能改變列的數量。

+0

好的,這是一個特定的...是否有可能做一些循環?或者是一個普通的聲明是絕對不可能的? – Megachip 2013-02-08 14:34:04

+0

循環訪問SQL中的數據不是一種情況。使用另一個級別(C#,PHP或您正在使用的其他語言)。 – 2013-02-08 14:39:49

+0

@RomanBadiornyi,正如問題所述,它是一個技術問題,而不是一個「使用問題」 – Megachip 2013-02-08 18:25:28