大家好,并提前感谢您的帮助!
我正在尝试根据返回的查询创建交叉表类型查询结果。 第一个查询:
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
- 我返回的name
是可变的,具体取决于customerId,也取决于其他类似查询中出现的其他where子句。
有没有办法将name
字段的结果作为第二个表中的列标题进行数据转换,第二个查询将计算在另一个匹配字段中显示的特定名称的出现次数?
B NO S V
PackA 250 120 61 22
PackB 100 23 62 37
PackC 50 102 11 39
请记住,列标题是根据第一个查询的结果而变化的。
据我所知,我需要制作一个php数组并遍历sql结果
答案 0 :(得分:2)
这种类型的查询称为 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;
但是如果names
的值或数量未知,那么您可以使用预准备语句来创建要执行的dyanmic 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;
答案 1 :(得分:1)
这应该适合你:
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
答案 2 :(得分:0)
如果提供的答案不合适,因为您事先并不知道name
字段的值并且不想使用准备好的语句,则可以随时添加另一级别的分组并执行应用程序代码中的“pivot”。选择可能看起来像
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中构建数据透视表所需的二维数组(假设此处为PDO,但基本要点与通过其他库迭代结果集相同):
$final_array = array();
while($row = $statement->fetchObject()) {
$final_array[$row->name][$row->other_field] = $row->NumberOfDispos;
}