1

我有两张桌子:

CREATE TABLE 'sales_sheet' (
  `_id` int(11) NOT NULL AUTO_INCREMENT,
  `_typed_by` int(11) DEFAULT NULL,
  `_product_id` int(11) DEFAULT NULL,
  `_year` date DEFAULT NULL,
  `_validation_state` int(11) DEFAULT NULL,
  PRIMARY KEY  (`_id`),
  KEY `_product_id` (`_product_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE 'sales_sheet_entries' (
  `_id` int(11) NOT NULL AUTO_INCREMENT,
  `_sheet_id` int(11) DEFAULT NULL,
  `_month` date DEFAULT NULL,
  `_quantity` int(11) DEFAULT NULL,
  PRIMARY KEY  (`_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

这两个表用于存储年销售额表。第一个表存储产品标识符、年份和工作表的验证状态。第二个存储产品的月销售额。

我想,在一个查询中得到这个结果:

---------------------------------------------
| Month         | Sales volume  |
---------------------------------------------
| January 2010      |       |
| February 2010     | XXXXXX    |
| March 2010        | XXXXXX    |
| April 2010        | XXXXXX    |
| May 2010          |       |
| June 2010         |       |
| July 2010         |       |
| August 2010       |       |
| September 2010        |       |
| October 2010      | XXXXXX    |
| November 2010     | XXXXXX    |
| December 2010     |       |
---------------------------------------------

销售量列中的空字段可能对应于已经保存在sales_sheet_entries表中但没有对应的销售量或数据库中根本不存在的记录,但查询必须显示它。

我的限制之一是我不能将 12 列直接对应于sales_sheet表中的月份列表,因为客户规范正在发生变化,他可能会要求按期间而不是按月份填写销量。

我希望我足够清楚,提前感谢您的帮助和对不起我的英语。

4

1 回答 1

1

MySQL 没有递归功能,因此您只能使用 NUMBERS 表技巧 -

  1. 创建一个只包含递增数字的表 - 使用 auto_increment 很容易做到:

    DROP TABLE IF EXISTS `example`.`numbers`;
    CREATE TABLE  `example`.`numbers` (
      `id` int(10) unsigned NOT NULL auto_increment,
       PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
  2. 使用以下方法填充表:

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ...根据需要获取尽可能多的值。

  3. 使用DATE_ADD构造时间列表,根据 NUMBERS.id 值增加月份:

    SELECT x.*
      FROM (SELECT DATE_ADD('2010-01-01', INTERVAL n.id - 1 MONTH)
              FROM numbers n) x
    
  4. LEFT JOIN 根据日期时间部分加入您的数据表:

       SELECT DATE_FORMAT(x.dt, '%M %Y') AS Month,
              y.sales_volume
         FROM (SELECT DATE_ADD('2010-01-01', INTERVAL n.id - 1 MONTH) AS dt
                 FROM numbers n) x
    LEFT JOIN (SELECT ss._product_id,
                      ss._year,
                      sse._month,
                      SUM(sse._quantity) AS sales_volume
                 FROM SALES_SHEET ss
                 JOIN SALES_SHEET_ENTRIES sse ON sse._sheet_id = ss._id
              GROUP BY ss._product_id, ss._year, sse._month) y ON y._month = MONTH(x.dt)
                                                              AND y._year = YEAR(x.dt)
                                                              AND y._product_id = ?
    
于 2010-08-11T18:46:58.903 回答