社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

如何通过查询将mysql组中的日期列值转换为列名[重复]

Wolverine • 4 年前 • 979 次点击  

如果我有一个类似这样的mysql表:

company_name    action  pagecount
-------------------------------
Company A       PRINT   3
Company A       PRINT   2
Company A       PRINT   3
Company B       EMAIL   
Company B       PRINT   2
Company B       PRINT   2
Company B       PRINT   1
Company A       PRINT   3

是否可以运行mysql查询以获得如下输出:

company_name    EMAIL   PRINT 1 pages   PRINT 2 pages   PRINT 3 pages
-------------------------------------------------------------
CompanyA        0       0               1               3
CompanyB        1       1               2               0

我的想法是 pagecount 可以改变,因此输出列的数量应该反映,每一列 action / 总页数 配对,然后每次点击次数 company_name . 我不确定这是否称为透视表,但有人建议这样做?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/44013
 
979 次点击  
文章 [ 8 ]  |  最新文章 4 年前
irba
Reply   •   1 楼
irba    10 年前
select t3.name, sum(t3.prod_A) as Prod_A, sum(t3.prod_B) as Prod_B, sum(t3.prod_C) as    Prod_C, sum(t3.prod_D) as Prod_D, sum(t3.prod_E) as Prod_E  
from
(select t2.name as name, 
case when t2.prodid = 1 then t2.counts
else 0 end  prod_A, 

case when t2.prodid = 2 then t2.counts
else 0 end prod_B,

case when t2.prodid = 3 then t2.counts
else 0 end prod_C,

case when t2.prodid = 4 then t2.counts
else 0 end prod_D, 

case when t2.prodid = "5" then t2.counts
else 0 end prod_E

from 
(SELECT partners.name as name, sales.products_id as prodid, count(products.name) as counts
FROM test.sales left outer join test.partners on sales.partners_id = partners.id
left outer join test.products on sales.products_id = products.id 
where sales.partners_id = partners.id and sales.products_id = products.id group by partners.name, prodid) t2) t3

group by t3.name ;
Talha
Reply   •   2 楼
Talha    7 年前

正确答案是:

select table_record_id,
group_concat(if(value_name='note', value_text, NULL)) as note
,group_concat(if(value_name='hire_date', value_text, NULL)) as hire_date
,group_concat(if(value_name='termination_date', value_text, NULL)) as termination_date
,group_concat(if(value_name='department', value_text, NULL)) as department
,group_concat(if(value_name='reporting_to', value_text, NULL)) as reporting_to
,group_concat(if(value_name='shift_start_time', value_text, NULL)) as shift_start_time
,group_concat(if(value_name='shift_end_time', value_text, NULL)) as shift_end_time
from other_value
where table_name = 'employee'
and is_active = 'y'
and is_deleted = 'n'
GROUP BY table_record_id
Peter Green
Reply   •   3 楼
Peter Green    9 年前

有一个名为mysql pivot table generator的工具,它可以帮助您创建基于web的pivot table,以后可以导出到excel(如果您愿意)。如果数据位于一个表或多个表中,则它可以工作。

您只需指定列(它支持动态列)、行、表体中的值和表关系(如果有)的数据源。 MySQL Pivot Table

这个工具的主页是 http://mysqlpivottable.net

Erwin Brandstetter
Reply   •   4 楼
Erwin Brandstetter    9 年前

标准SQL 版本使用 boolean logic :

SELECT company_name
     , COUNT(action = 'EMAIL' OR NULL) AS "Email"
     , COUNT(action = 'PRINT' AND pagecount = 1 OR NULL) AS "Print 1 pages"
     , COUNT(action = 'PRINT' AND pagecount = 2 OR NULL) AS "Print 2 pages"
     , COUNT(action = 'PRINT' AND pagecount = 3 OR NULL) AS "Print 3 pages"
FROM   tbl
GROUP  BY company_name;

SQL Fiddle.

怎么用?

TRUE OR NULL 产量 TRUE .
FALSE OR NULL 产量 NULL .
NULL OR NULL 产量 无效的 .
COUNT 仅统计非空值。VoRE

Abhishek Gupta
Reply   •   5 楼
Abhishek Gupta    9 年前

对于动态轴,使用 GROUP_CONCAT 具有 CONCAT . 这个 GROUP_CONCAT 函数将组中的字符串连接为一个具有各种选项的字符串。

SET @sql = NULL;
SELECT
    GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(CASE WHEN action = "',
      action,'"  AND ', 
           (CASE WHEN pagecount IS NOT NULL 
           THEN CONCAT("pagecount = ",pagecount) 
           ELSE pagecount IS NULL END),
      ' THEN 1 ELSE 0 end) AS ',
      action, IFNULL(pagecount,'')

    )
  )
INTO @sql
FROM
  t;

SET @sql = CONCAT('SELECT company_name, ', @sql, ' 
                  FROM t 
                   GROUP BY company_name');

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

DEMO HERE

shA.t
Reply   •   6 楼
shA.t    8 年前

对于MySQL,您可以直接将条件放在 SUM() 功能,它将 计算为布尔值 0 1 这样你就可以根据你的标准而不使用 IF/CASE 声明

SELECT
    company_name,  
    SUM(action = 'EMAIL')AS Email,
    SUM(action = 'PRINT' AND pagecount = 1)AS Print1Pages,
    SUM(action = 'PRINT' AND pagecount = 2)AS Print2Pages,
    SUM(action = 'PRINT' AND pagecount = 3)AS Print3Pages
FROM t
GROUP BY company_name

DEMO

shA.t
Reply   •   7 楼
shA.t    8 年前

我的解决方案是在没有任何轴心的t-sql中:

SELECT
    CompanyName,  
    SUM(CASE WHEN (action='EMAIL') THEN 1 ELSE 0 END) AS Email,
    SUM(CASE WHEN (action='PRINT' AND pagecount=1) THEN 1 ELSE 0 END) AS Print1Pages,
    SUM(CASE WHEN (action='PRINT' AND pagecount=2) THEN 1 ELSE 0 END) AS Print2Pages,
    SUM(CASE WHEN (action='PRINT' AND pagecount=3) THEN 1 ELSE 0 END) AS Print3Pages
FROM 
    Company
GROUP BY 
    CompanyName
robsch
Reply   •   8 楼
robsch    8 年前

基本上 一张透视表。

一个很好的教程,关于如何实现这一点可以在这里找到: http://www.artfulsoftware.com/infotree/qrytip.php?id=78

我建议你读这篇文章,并根据你的需要调整这个解决方案。

更新

在上面的链接不再可用之后,我觉得有必要为在这里搜索mysql pivot答案的所有人提供一些附加信息。它确实有大量的信息,我不会把所有的信息都放在这里(因为我只是不想复制他们丰富的知识),但是我会给出一些关于如何用sql方式处理数据透视表的建议,比如peku在第一个例子中提出的问题。地点。

也许链接很快就会回来,我会留意的。

电子表格方式…

很多人只是为了这个目的使用msexcel、openoffice或其他电子表格工具。这是一个有效的解决方案,只需复制那边的数据,然后使用gui提供的工具来解决这个问题。

但是…这不是问题所在,它甚至可能导致一些缺点,比如如何将数据放入电子表格,有问题的缩放等等。

SQL方式…

鉴于他的桌子看起来像这样:

CREATE TABLE `test_pivot` (
  `pid` bigint(20) NOT NULL AUTO_INCREMENT,
  `company_name` varchar(32) DEFAULT NULL,
  `action` varchar(16) DEFAULT NULL,
  `pagecount` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`pid`)
) ENGINE=MyISAM;

现在看看他/她想要的桌子:

company_name    EMAIL   PRINT 1 pages   PRINT 2 pages   PRINT 3 pages
-------------------------------------------------------------
CompanyA        0       0               1               3
CompanyB        1       1               2               0

行( EMAIL , PRINT x pages )类似的情况。主要分组依据 company_name .

为了设置条件,这相当需要使用 CASE -声明。为了分组,好吧,用… GROUP BY .

提供这个支点的基本SQL可以是这样的:

SELECT  P.`company_name`,
    COUNT(
        CASE 
            WHEN P.`action`='EMAIL' 
            THEN 1 
            ELSE NULL 
        END
    ) AS 'EMAIL',
    COUNT(
        CASE 
            WHEN P.`action`='PRINT' AND P.`pagecount` = '1' 
            THEN P.`pagecount` 
            ELSE NULL 
        END
    ) AS 'PRINT 1 pages',
    COUNT(
        CASE 
            WHEN P.`action`='PRINT' AND P.`pagecount` = '2' 
            THEN P.`pagecount` 
            ELSE NULL 
        END
    ) AS 'PRINT 2 pages',
    COUNT(
        CASE 
            WHEN P.`action`='PRINT' AND P.`pagecount` = '3' 
            THEN P.`pagecount` 
            ELSE NULL 
        END
    ) AS 'PRINT 3 pages'
FROM    test_pivot P
GROUP BY P.`company_name`;

这将很快提供所需的结果。这种方法的主要缺点是,在透视表中需要的行越多,在sql语句中需要定义的条件就越多。

这也可以处理,因此人们倾向于使用准备好的语句、例程、计数器等。

有关此主题的其他链接: