sql >> Base de Datos >  >> RDS >> Mysql

Sentencia SQL - Matriz SQL

Hay dos formas de girar datos en MySQL. Si conoce los valores con anticipación (equipos), codificará los valores o puede usar una declaración preparada para generar sql dinámico.

Una versión estática sería:

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 con demostración

Si desea utilizar una versión dinámica con una declaración preparada, el código sería:

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 con demostración .

Edición n. ° 1, después de pensar en esto, en realidad haría esto un poco diferente. Generaría una verdadera matriz de los datos donde aparecían los equipos tanto en la fila como en la columna. Para hacer esto, primero usaría un UNION ALL consulta para obtener todos los equipos en dos columnas:

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

Consulte SQL Fiddle con demostración . Una vez hecho esto, pivotar los datos:

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 con demostración . Lo que da un resultado más detallado 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 |