【问题标题】:How to pivot record based on week number in mysql?如何根据mysql中的周数透视记录?
【发布时间】:2020-08-12 15:38:23
【问题描述】:

我可以轻松地以日期为单位调整结果,但在周数方面却无法做到这一点。

表结构exp.

CREATE TABLE `products` (
  `product_name` varchar(250) DEFAULT NULL,
  `date` date DEFAULT NULL,
  `sales` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

/*Data for the table `products` */
insert  into `products`(`product_name`,`date`,`sales`) values 
('Micro','2020-08-01',100),
('Micro','2020-08-02',200),
('x','2020-08-02',300),
('y','2020-08-01',300),
('z','2020-08-03',400),
('x','2020-08-03',400),
('y','2020-08-10',500),
('z','2020-08-10',500),
('x','2020-08-10',500),
('y','2020-08-10',500),
('z','2020-08-10',500),
('x','2020-08-10',500),
('y','2020-08-10',500),
('z','2020-08-10',500),
('x','2020-08-11',230),
('y','2020-08-11',210),
('z','2020-08-11',240);

按日期显示销售总额的查询如下我使用的mysql代码

SET SESSION group_concat_max_len = 10000;

DROP TEMPORARY TABLE IF EXISTS temp_sale;
CREATE TEMPORARY TABLE temp_sale
SELECT `date`,product_name,SUM(sales) AS sales FROM 
products
WHERE DATE BETWEEN DATE_ADD("2020-08-12",INTERVAL -29 DAY) AND "2020-08-12" 
GROUP BY `date`,product_name;

SELECT * FROM temp_sale;

// this code is used to get the result on date wise pivot
SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(CASE WHEN date = ''',
      DATE_FORMAT(DATE, '%Y-%m-%d'),
      ''' THEN round(sales,2) end) AS `',
      
      DATE_FORMAT(DATE, '%Y-%m-%d'), '`'
    )
  ) INTO @sql
  
  FROM `temp_sale` WHERE DATE BETWEEN DATE_ADD("2020-08-12",INTERVAL -29 DAY) AND "2020-08-12" ;




SET @final_query = CONCAT('select product_name,',@sql,' from temp_sale
group by product_name');

PREPARE stmt FROM @final_query;
EXECUTE stmt;

上述查询的输出如下所示

但问题是我需要按周计算销售记录的总和。像

Product_name | sales | week-31 | week- 32 | week- 33

请在此处帮助按周数动态透视数据。

【问题讨论】:

    标签: mysql pivot


    【解决方案1】:

    此数据透视表无需临时表即可满足您的需求

    CREATE TABLE `products` (
      `product_name` varchar(250) DEFAULT NULL,
      `date` date DEFAULT NULL,
      `sales` int(11) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
    /*Data for the table `products` */
    insert  into `products`(`product_name`,`date`,`sales`) values 
    ('Micro','2020-08-01',100),
    ('Micro','2020-08-02',200),
    ('x','2020-08-02',300),
    ('y','2020-08-01',300),
    ('z','2020-08-03',400),
    ('x','2020-08-03',400),
    ('y','2020-08-10',500),
    ('z','2020-08-10',500),
    ('x','2020-08-10',500),
    ('y','2020-08-10',500),
    ('z','2020-08-10',500),
    ('x','2020-08-10',500),
    ('y','2020-08-10',500),
    ('z','2020-08-10',500),
    ('x','2020-08-11',230),
    ('y','2020-08-11',210),
    ('z','2020-08-11',240);
    
    SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'max(CASE WHEN date = ''',
          DATE_FORMAT(DATE, '%Y-%m-%d'),
          ''' THEN round(sales,2) end) AS `',
          
          DATE_FORMAT(DATE, '%Y-%m-%d'), '`'
        )
      ) INTO @sql
      
      FROM `temp_sale` WHERE DATE BETWEEN DATE_ADD("2020-08-12",INTERVAL -29 DAY) AND "2020-08-12" ;
    
    SELECT 
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'SUM(CASE WEEK(`date`) WHEN "',
         WEEK(`date`),
          '" THEN `sales` ELSE 0 END) AS `',
          CONCAT('week-',WEEK(`date`)), '`'      
        )
        ORDER BY WEEK(`date`)
      ) 
      INTO @sql
    FROM products as p
    
    SET @sql = CONCAT('select product_name,SUM(`sales`), ',@sql,' from products
    group by product_name');
    
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    产品名称 |总和(`销售额`) |第 30 周 |第 31 周 |第 32 周 :----------- | ------------: | ------: | ------: | ------: 微 | 300 | 100 | 200 | 0 x | 1930 | 0 | 700 | 1230 是 | 2010 | 300 | 0 | 1710 z | 2140 | 0 | 400 | 1740

    db小提琴here

    【讨论】:

    • 如果一周后两年??
    • 那么你还需要包括年份。但是你可以通过生成数据来测试它
    • 我看到的唯一问题是,当您获得大于 1 的数据时,您需要一周内有很多数据,因为它来自不同年份,因此您可以使用年(date)请accept the answer
    猜你喜欢
    • 2019-10-01
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多