在SQL中的交叉表视图?

cjv*_*cjv 2 mysql sql view

我不知道我的标题是正确的,但让我解释一下我在寻找什么.

我有两张桌子.

客户端

clID   (primary key)
ClName (varchar)
Run Code Online (Sandbox Code Playgroud)

比分

ID     (Primay key)
clID   (F Key)
PlayDate  (Date/Time)
Score     (double)
Run Code Online (Sandbox Code Playgroud)

客户表数据如下所示

clID  clName
1     Chris
2     Gale
3     Donna
Run Code Online (Sandbox Code Playgroud)

分数表数据如下所示

ID  clID  PlayDate    Score
1   2     23/01/2012  -0.0125
2   2     24/01/2012  0.1011
3   3     24/01/2012  0.0002
4   3     26/01/2012  -0.0056
5   3     27/01/2012  0.0001
6   1     12/01/2012  0.0122
7   1     13/01/2012  0.0053
Run Code Online (Sandbox Code Playgroud)

是否可以创建一个看起来像这样的视图

Date         Chris   Gale    Donna
12/01/2012   0.0122   -        -
13/01/2012   0.0053   -        -
23/01/2012     -     -0.0125   -
24/01/2012     -     0.1011  0.0002
26/01/2012     -        -    -0.0056
27/01/2012     -        -    0.0001
Run Code Online (Sandbox Code Playgroud)

如果稍后有另一个新客户端,那么我应该能够在新列中检查该新客户端的数据,该新列将在此视图中创建.

提前致谢.

Tar*_*ryn 6

这种类型的数据转换称为PIVOT.MySQL没有pivot函数,但你可以使用带有CASE表达式的聚合函数来获得结果.

如果clients提前知道名称,那么您可以对查询进行硬编码:

select s.playdate,
  sum(case when clname = 'Chris' then score end) Chris,
  sum(case when clname = 'Gale' then score end) Gale,
  sum(case when clname = 'Donna' then score end) Donna
from clients c
inner join scores s
  on c.clid = s.clid
group by s.playdate;
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.

如果您拥有未知数量的客户端,或者您将添加要包含的新客户端而无需更改代码,则可以使用预准备语句生成动态SQL:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(CASE WHEN clName = ''',
      clName,
      ''' THEN score else ''-'' END) AS `',
      clName, '`'
    )
  ) INTO @sql
FROM clients;

SET @sql 
  = CONCAT('SELECT s.playdate, ', @sql, ' 
            from clients c
            inner join scores s
              on c.clid = s.clid
            group by s.playdate');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.两个查询都会给出相同的结果.