douci1196 2013-01-10 22:45
浏览 39
已采纳

Mysql-PHP,基于变量字段的旋转/交叉制表符

Hello Everybody and thank you in advance for your help!

I am trying to create a crosstab type query result based on a returned query. The first query :

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`

resulting in:

Name NumberofDispos
B      400
NO     245
S      134
V      98

-- The name that I'm returning are variable depending on the customerId, and also on additional where clauses that appear on other similar queries.

Is there a way to pivot the results of the name field as column headings in a second table, which a second query will count the occurances of that particular name showing up in another matched field?

        B   NO  S   V 
PackA   250 120 61  22
PackB   100 23  62  37
PackC   50  102 11  39

Please keep in mind the column headings are variable based on the results fromt the first query.

As far as I can tell, I would need to make a php array and iterate through the sql results

  • 写回答

3条回答 默认 最新

  • dtcmadj31951 2013-01-10 23:08
    关注

    This type of query is known as a pivot but unfortunately MySQL does not have a pivot function so you will want to replicate it using an aggregate function with a CASE statement.

    If the values are known ahead of time, then you can hard-code the values into the following:

    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;
    

    But if the values or number of names are unknown then you can use a prepared statement which creates a dyanmic sql statement to execute. The code will look like this:

    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;
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog