Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL语句-SQL矩阵_Mysql_Sql_Pivot - Fatal编程技术网

Mysql SQL语句-SQL矩阵

Mysql SQL语句-SQL矩阵,mysql,sql,pivot,Mysql,Sql,Pivot,对于下表,是否可以创建SQL语句来创建数据矩阵或视图 表格: 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 |

对于下表,是否可以创建SQL语句来创建数据矩阵或视图

表格:

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
结果矩阵:

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

不能创建列数可变的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语句都有一组预定义的列。您不能改变列数。

有两种方法可以在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;
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;

如果要将动态版本与准备好的语句一起使用,则代码为:

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;
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;

编辑#1,考虑到这一点后,我实际上会做一些不同的事情。我将生成一个真实的矩阵,用于记录团队同时出现在行和列中的数据。为此,首先使用
UNION ALL
查询将所有团队分为两列:

select teama Team1, teamb Team2,
  won-lost Total
from yourtable
union all
select teamb, teama,
  won-lost
from yourtable
看。完成后,您将以数据为轴心:

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;
看。其中给出了以下更详细的结果:

| 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 |

对于五支球队的具体情况来说,这样做并不难,但是一个能够扩展到任意数量的球队和比赛的通用解决方案仅仅使用sql是相当棘手的。数据库是用来保存和获取数据的,而不是很好地格式化数据。这是在表示层完成的@超级芯片。这两个都是矩阵。它们只是以不同的方式表示。@tombom,我知道,但问题是,它是否可能(以及哪个sql语句将生成它),不是有用的还是推荐的。@Gordon,是的,我很抱歉。不是我的母语好吧,那是一种特殊的语言。。。可以做一些循环吗?或者泛型语句是不可能的?在SQL中不能循环数据。使用另一个级别(C#、php或您正在使用的另一种语言)。@RomanBadiornyi,如前所述,这是一个技术问题,而不是“使用问题”@Megachip您能用数据样本编辑sql吗?然后将链接作为注释发布。@Megachip问题在于
组的长度限制。您必须将其展开(请参阅)。这是一把工作小提琴——THX很多。我想这解决了我的问题。除了这是一个特定于mysql的解决方案外,它是SQL中的一个解决方案;)@Megachip静态版本可用于任何数据库。对于动态解决方案,它必须是特定于数据库的,每一个都有自己的语法。@Megachip我对我的答案做了一点调整,并包括了一种生成更详细结果的方法,所有团队都以行和列的形式出现。