【问题标题】:MySQL pivot with 3 tables带有 3 个表的 MySQL 数据透视表
【发布时间】:2015-11-17 06:46:00
【问题描述】:

我搜索并查看了有关从 MySQL 中旋转(动态)数据的各种帖子。我已经设法让它在一张桌子上工作,但是当我试图用三张桌子来做这件事时,我遇到了一个障碍。有人能指出我正确的方向吗?

  • 表 1:供应商(我们购买的供应商列表)
  • 表 2:标准(每个供应商设置的标准)
  • 表 3:矩阵(用于 以上两种)

我想要实现的是这样的矩阵/枢轴:

           Criteria1        Criteria2        Criteria3 
Vendor 1   ValueFromMatrix  ValueFromMatrix  ValueFromMatrix
Vendor 2   ValueFromMatrix  ValueFromMatrix  ValueFromMatrix
Vendor 3   ValueFromMatrix  ValueFromMatrix  ValueFromMatrix

此表的使用示例:

           MinOrderQty        MinOrderValue        ReturnsAllowed 
Intel      1000                5000.00             RMA required
AMD        2000               15000.00             No
nVidia     9000                8000.00             RMA + dropship

供应商和标准的数量是动态的,可以由用户添加/删除,所以我不能硬编码从行到列的转换。

ValueFromMatrix 是 Varchar(200) 字段并包含文本。它通过使用 VendorID 和 CriteriaID (int) 字段链接另外两个表。

我只是在这里碰了壁,我没有运气破译我见过的一些例子。

表格代码:

CREATE TABLE `vendors` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `vendor_name` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;


CREATE TABLE `criteria` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `criteria_desc` varchar(150) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;


CREATE TABLE `matrix` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `vendor_id` int(11) DEFAULT NULL,
  `criteria_id` int(11) DEFAULT NULL,
  `criteria_response` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=latin1;

SQL Fiddle of DB schema/data

criteria_response 字段用于填充上表示例中的 ValueFromMatrix。

如果有人能指出我正确的方向,我将不胜感激。我只是没有看到任何讨论三个表来生成此视图的示例,而且我一直卡住。

谢谢。

【问题讨论】:

    标签: mysql pivot


    【解决方案1】:

    试试这个改编自我早期答案之一的查询(改编自this question/answer):

    SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'MAX(CASE WHEN criteria_id = ''',
          criteria_id,
          ''' THEN criteria_response END) AS `',
          criteria_desc, '`'
        )
      ) INTO @sql
    FROM  matrix m JOIN criteria c ON m.criteria_id = c.id;
    
    SET @sql = CONCAT('SELECT V.vendor_name, ', @sql, ' 
                      FROM matrix m
                      JOIN vendors v ON m.vendor_id = v.id
                      JOIN criteria c on m.criteria_id = c.id
                      GROUP BY v.id');
    
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    

    Sample SQL Fiddle

    【讨论】:

    • 太好了,完美运行,谢谢!完全靠我自己是做不到的。
    • @SparkyUK 尝试在第一条语句中添加 where 子句:WHERE criteria_desc != 'ReturnsAllowed';
    • 感谢 jpw,我想通了并删除了我的评论,但感谢您确认我已将其放在正确的位置。 :)
    • 关于 Where 子句的另一个问题 - 我正在做 Where c.id IN (1,4),它显然会带回 Criteria ID 1 和 4。为什么当我将它作为 SP 参数传递时这不起作用? c.id 在哪里 (SelectedCols) ?我用您的代码创建了一个 SP,在 SP 的顶部添加了(在 SelectedCols 文本中),但我只收到错误消息:“预期 1 个参数,得到 2”。有什么想法吗?
    • @SparkyUK 您不能以这种方式将数组或列表作为参数传递。不过有一些方法可以做到;我不熟悉如何在 MySQL 中最好地完成此操作,但请参阅此答案以获得一些可能的指导:stackoverflow.com/a/11957706/1175077
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    • 2016-10-20
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多