Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Instrução SQL - Matriz SQL


Há duas maneiras de girar dados no MySQL. Se você souber os valores com antecedência (equipes), você codificará os valores ou poderá usar uma instrução preparada para gerar sql dinâmico.

Uma versão estática seria:
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;

Consulte SQL Fiddle with Demo

Se você quiser usar uma versão dinâmica com uma instrução preparada, o código seria:
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;

Consulte SQL Fiddle with Demo .

Edit # 1, depois de pensar sobre isso, eu realmente faria isso um pouco diferente. Eu geraria uma verdadeira matriz dos dados onde as equipes apareciam tanto na linha quanto na coluna. Para fazer isso, você primeiro usaria um UNION ALL query para obter todas as equipes em duas colunas:
select teama Team1, teamb Team2,
  won-lost Total
from yourtable
union all
select teamb, teama,
  won-lost
from yourtable

Consulte SQL Fiddle with Demo . Feito isso, você gira os dados:
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;

Consulte SQL Fiddle with Demo . O que dá um resultado mais detalhado de:
| 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 |