Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.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将行透视为动态列数_Mysql_Sql_Pivot - Fatal编程技术网

MySQL将行透视为动态列数

MySQL将行透视为动态列数,mysql,sql,pivot,Mysql,Sql,Pivot,假设我有三个不同的MySQL表: 表产品: id | name 1 Product A 2 Product B id | name 1 Partner A 2 Partner B 表合作伙伴: id | name 1 Product A 2 Product B id | name 1 Partner A 2 Partner B 表销售额: partners_id | products_id 1 2

假设我有三个不同的MySQL表:

产品

id | name
 1   Product A
 2   Product B
id | name
 1   Partner A
 2   Partner B
合作伙伴

id | name
 1   Product A
 2   Product B
id | name
 1   Partner A
 2   Partner B
销售额

partners_id | products_id
          1             2
          2             5
          1             5
          1             3
          1             4
          1             5
          2             2
          2             4
          2             3
          1             1
我想得到一个表,其中合作伙伴在行中,产品在列中。到目前为止,我能够得到如下输出:

name      | name      | COUNT( * )
Partner A   Product A          1
Partner A   Product B          1
Partner A   Product C          1
Partner A   Product D          1
Partner A   Product E          2
Partner B   Product B          1
Partner B   Product C          1
Partner B   Product D          1
Partner B   Product E          1
SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'count(case when Product_Name = ''',
      Product_Name,
      ''' then 1 end) AS ',
      replace(Product_Name, ' ', '')
    )
  ) INTO @sql
from products;

SET @sql = CONCAT('SELECT pt.partner_name, ', @sql, ' from partners pt
left join sales s
  on pt.part_id = s.partner_id
left join products pd
  on s.product_id = pd.prod_id
group by pt.partner_name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
使用此查询:

SELECT partners.name, products.name, COUNT( * ) 
FROM sales
JOIN products ON sales.products_id = products.id
JOIN partners ON sales.partners_id = partners.id
GROUP BY sales.partners_id, sales.products_id
LIMIT 0 , 30
但我想换成这样:

partner_name | Product A | Product B | Product C | Product D | Product E
Partner A              1           1           1           1           2
Partner B              0           1           1           1           1
问题是,我无法说出我将拥有多少产品,因此列号需要根据products表中的行动态更改


这个非常好的答案似乎对mysql不起作用:

不幸的是,mysql没有一个基本上就是您要做的
PIVOT
函数。因此,您需要将聚合函数与
CASE
语句一起使用:

select pt.partner_name,
  count(case when pd.product_name = 'Product A' THEN 1 END) ProductA,
  count(case when pd.product_name = 'Product B' THEN 1 END) ProductB,
  count(case when pd.product_name = 'Product C' THEN 1 END) ProductC,
  count(case when pd.product_name = 'Product D' THEN 1 END) ProductD,
  count(case when pd.product_name = 'Product E' THEN 1 END) ProductE
from partners pt
left join sales s
  on pt.part_id = s.partner_id
left join products pd
  on s.product_id = pd.prod_id
group by pt.partner_name

由于您不知道产品,您可能希望动态执行此操作。这可以使用准备好的语句来完成

使用动态数据透视表(将行转换为列),您的代码如下所示:

name      | name      | COUNT( * )
Partner A   Product A          1
Partner A   Product B          1
Partner A   Product C          1
Partner A   Product D          1
Partner A   Product E          2
Partner B   Product B          1
Partner B   Product C          1
Partner B   Product D          1
Partner B   Product E          1
SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'count(case when Product_Name = ''',
      Product_Name,
      ''' then 1 end) AS ',
      replace(Product_Name, ' ', '')
    )
  ) INTO @sql
from products;

SET @sql = CONCAT('SELECT pt.partner_name, ', @sql, ' from partners pt
left join sales s
  on pt.part_id = s.partner_id
left join products pd
  on s.product_id = pd.prod_id
group by pt.partner_name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;


可能值得注意的是,
GROUP\u CONCAT
默认限制为1024字节。您可以通过在整个过程中将其设置得更高来解决此问题,即。
SET@@group\u concat\u max\u len=32000

结尾关于“max_len”的评论是一个救星!感谢您的提示。如果您正在寻找更多动态pivot查询,请检查以下内容:如果partners pt的产品名称为
ProductA'),会发生什么情况;截断合作伙伴@avatarofhope2这是一个问题还是一种暗示?如果这提供了一个注入角度,那么什么是正确的处理方法?请参阅链接以获取多个建议。@BhavinPokiya,这是您提供的MS SQL Server链接,而它被标记为MySQL。