Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/296.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.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 PHP,基于变量字段的数据透视/交叉表_Php_Mysql_Variables_Pivot_Crosstab - Fatal编程技术网

Mysql PHP,基于变量字段的数据透视/交叉表

Mysql PHP,基于变量字段的数据透视/交叉表,php,mysql,variables,pivot,crosstab,Php,Mysql,Variables,Pivot,Crosstab,大家好,提前谢谢你们的帮助 我正在尝试基于返回的查询创建交叉表类型的查询结果。 第一个查询: SELECT DISTINCT dc.`name`, Count(pd.dispositionCodeId) AS NumberOfDispos FROM pd JOIN ph ON (pd.packetHeaderId = ph.packetHeaderId) JOIN sc ON (sc.packetHeaderId = ph.packetHeaderId) JOIN dc ON pd.di

大家好,提前谢谢你们的帮助

我正在尝试基于返回的查询创建交叉表类型的查询结果。 第一个查询:

SELECT DISTINCT
dc.`name`,
Count(pd.dispositionCodeId) AS NumberOfDispos
FROM
pd

 JOIN ph ON (pd.packetHeaderId = ph.packetHeaderId)
 JOIN sc ON (sc.packetHeaderId = ph.packetHeaderId)
 JOIN dc ON pd.dispositionCodeId = dc.dpcodeId
WHERE (`ph`.`customerId` = 60)
GROUP BY
dc.`name`
导致:

Name NumberofDispos
B      400
NO     245
S      134
V      98
-我返回的名称是可变的,这取决于customerId,以及其他类似查询中出现的其他where子句

是否有一种方法可以将name字段的结果作为第二个表中的列标题进行透视,第二个查询将统计在另一个匹配字段中显示的特定名称的发生率

        B   NO  S   V 
PackA   250 120 61  22
PackB   100 23  62  37
PackC   50  102 11  39
请记住,根据第一次查询的结果,列标题是可变的


据我所知,我需要制作一个php数组并遍历sql结果

这应该适合您:

SELECT 
  pd.dispositionCodeId,
  SUM(CASE WHEN dc.`Name` = 'B' THEN 1 ELSE 0 END 0) AS B,
  SUM(CASE WHEN dc.`Name` = 'NO' THEN 1 ELSE 0 END 0) AS NO,
  SUM(CASE WHEN dc.`Name` = 'S' THEN 1 ELSE 0 END 0) AS S,
  SUM(CASE WHEN dc.`Name` = 'V' THEN 1 ELSE 0 END 0) AS V
FROM pd
JOIN ph ON (pd.packetHeaderId = ph.packetHeaderId)
JOIN sc ON (sc.packetHeaderId = ph.packetHeaderId)
JOIN dc ON pd.dispositionCodeId = dc.dpcodeId
WHERE (`ph`.`customerId` = 60)
GROUP BY pd.dispositionCodeId

这种类型的查询称为pivot,但不幸的是MySQL没有pivot函数,因此您需要使用聚合函数和CASE语句来复制它

如果提前知道这些值,则可以将这些值硬编码为以下内容:

SELECT pd.dispositionCodeId,
  sum(case when dc.`name` = 'B' then 1 else 0 end) B,
  sum(case when dc.`name` = 'NO' then 1 else 0 end) NO,
  sum(case when dc.`name` = 'S' then 1 else 0 end) S,
  sum(case when dc.`name` = 'V' then 1 else 0 end) V
FROM pd
JOIN ph 
  ON pd.packetHeaderId = ph.packetHeaderId
JOIN sc 
  ON sc.packetHeaderId = ph.packetHeaderId
JOIN dc 
  ON pd.dispositionCodeId = dc.dpcodeId
WHERE (`ph`.`customerId` = 60)
GROUP BY pd.dispositionCodeId;
但是,如果名称的值或数量未知,则可以使用一个准备好的语句来创建一个动态sql语句来执行。代码如下所示:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(case when dc.`name` = ''',
      name,
      ''' then 1 else 0 end) AS ',
      name
    )
  ) INTO @sql
FROM dc;

SET @sql = CONCAT('SELECT pd.dispositionCodeId, ', @sql, ' 
                   FROM pd
                   JOIN ph 
                     ON pd.packetHeaderId = ph.packetHeaderId
                   JOIN sc 
                     ON sc.packetHeaderId = ph.packetHeaderId
                   JOIN dc 
                     ON pd.dispositionCodeId = dc.dpcodeId 
                   WHERE `ph`.`customerId` = 60
                   GROUP BY pd.dispositionCodeId');

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

如果提供的答案不合适,因为您之前不知道name字段的值,也不想使用准备好的语句,那么您可以始终添加另一级别的分组,并在应用程序代码中执行pivot。select可能看起来像

SELECT
dc.`name` as `name`,
dc.`other_field` as `other_field`,
Count(pd.dispositionCodeId) AS NumberOfDispos
FROM
pd
 JOIN ph ON (pd.packetHeaderId = ph.packetHeaderId)
 JOIN sc ON (sc.packetHeaderId = ph.packetHeaderId)
 JOIN dc ON pd.dispositionCodeId = dc.dpcodeId
WHERE (`ph`.`customerId` = 60)
GROUP BY
dc.`name`,
dc.`other_field`
ORDER BY
dc.`name` ASC,
dc.`other_field` ASC
然后,您可以在PHP中构建pivot表所需的二维数组,就像这里假设PDO一样,但基本要点与使用其他库迭代结果集相同:

$final_array = array();
while($row = $statement->fetchObject()) {
    $final_array[$row->name][$row->other_field] = $row->NumberOfDispos;
}

谢谢你,PinnyM,虽然这是可行的,但我需要它来创建一个动态的已知列标题。然后你需要使用动态SQL-@bluefeet的答案应该适合你。谢谢你,bluefeet,这很接近,我在尝试类似的解决方案时遇到了类似的错误,不确定原因:从@SQL准备stmt;[Err]1064-您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,以了解在第行“Not Home,sumcase when disposition_codes.name=”门控社区“然后是1 else”附近使用的正确语法1@alex很难从错误消息中看出问题所在。可以用一些样本数据和您的表格创建一个吗?蓝脚,再次感谢您的帮助,请让我知道我的小提琴是否正确,这是我第一次:@alex the fiddle看起来不错。这里有两个sql版本——静态版本——动态版本。这些会产生你想要的结果吗?@alex这是一个社区志愿者论坛。因此,在我看来,除非被邀请,否则不适合进行专业接触。谢谢你,迈克,我会尝试一下。我真的很想在MySql中解决这个问题,然后再尝试用PHP进行分类。我将返回并让您知道这是如何工作的。@alex显然,动态列标题使MySQL中的情况更加复杂。我对仅使用MySQL的解决方案的担心是,查询本身可能变得非常复杂和缓慢,而在PHP中将数据读入多维数组实际上并不比读入更典型的数据库结果数组更困难。