1

私は2つのテーブルを持っています:

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;

これら 2 つのテーブルは、年間売上高のシートを格納するために使用されます。最初のテーブルには、シートの製品 ID、年、および検証ステータスが格納されます。2 つ目は、製品の月間売上を格納します。

私は、単一のクエリでこの結果を取得したい:

---------------------------------------------
| 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 テーブルに既に保存されているが、対応する売上高がないか、単にデータベースに存在しないレコードに対応している可能性がありますが、クエリはそれを表示する必要があります。

私の制約の 1 つは、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 に答える