5

良い一日。

SQLクエリでこの問題によってブロックされています:

次の表があるとします。

CREATE TABLE `Forecasted_Sales_tcl`(
`DEALER_id` varchar(15)NOT NULL、
`SALES_period`の日付はNULLではなく、
`TYPE` int(2)NOT NULL、
`UNIT_SALES` int(6)DEFAULT NULL、
`HEAD_OFFICE_CODE` varchar(15)DEFAULT NULL
主キー( `DEALER_CODE`、` SALES_MONTH`、 `TYPE`)
)ENGINE = InnoDB DEFAULT CHARSET = latin1;

http://sqlfiddle.com/#!2/b780c

今後数か月以内に可能な販売料金を生成する必要があります。たとえば、ある店舗で1か月(SALES_period)の「2012年6月」のアウトバウンド売上(unit_sales)をプロットしました。2012年8月にタイプA、2012年10月にタイプB、2012年12月にタイプCのサービス料金が発生することを期待しています。また、さまざまな店舗で、さまざまな月にアウトバウンド販売があります。

次のようなレポートを生成しようとしています。

  期間|料金A| チャージB|チャージC| store_id
2012年1月| X | Y | Z | (id)
2012年2月| :| :| ::
2012年3月| :| :| ::
2012年4月| :| :| ::
2012年5月| :| :| ::
2012年6月| :| :| ::
2012年7月| :| :| ::
2012年8月| :| :| ::
2012年9月| :| :| ::
2012年10月| :| :| ::
2012年11月| :| :| ::
2012年12月| :| :| ::

Xはストアのunit_sales(2か月前)の合計(id)Yはストアのunit_sales(4か月前)の合計(id)Zはストアのunit_sales(6か月前)の合計(id)


SQLフィドルといくつかのパラメーターに関する上記のデータが与えられた場合:レポートの生成:From:2012-06 To:2013-07

  期間| ディーラーID| チャージX| チャージB| チャージC|
 2012-06 | 0001 | 0 | 0 | 0 |
 2012-07 | 0001 | 0 | 0 | 0 |
 2012-08 | 0001 | 100 | 0 | 0 |
 2012-09 | 0001 | 0 | 0 | 0 |
 2012-10 | 0001 | 0 | 100 | 0 |
 2012-11 | 0001 | 0 | 0 | 0 |
 2012-12 | 0001 | 0 | 0 | 100 |
 2013-01 | 0001 | 0 | 0 | 0 |
 2013-02 | 0001 | 0 | 0 | 0 |
 2013-03 | 0001 | 0 | 0 | 0 |
 2013-04 | 0001 | 0 | 0 | 0 |
 2013-05 | 0001 | 0 | 0 | 0 |
 2013-06 | 0001 | 0 | 0 | 0 |
 2013-07 | 0001 | 0 | 0 | 0 |

  期間| ディーラーID| チャージA| チャージB| チャージC|
 2012-06 | 0002 | 0 | 10 | 2 |
 2012-07 | 0002 | 0 | 0 | 0 |
 2012-08 | 0002 | 10 | 0 | 0 |
 2012-09 | 0002 | 18 | 0 | 0 |
 2012-10 | 0002 | 5 | 10 | 0 |
 2012-11 | 0002 | 0 | 18 | 0 |
 2012-12 | 0002 | 0 | 5 | 10 |
 2013-01 | 0002 | 0 | 0 | 18 |
 2013-02 | 0002 | 0 | 0 | 5 |
 2013-03 | 0002 | 0 | 0 | 0 |
 2013-04 | 0002 | 0 | 0 | 0 |
 2013-05 | 0002 | 0 | 0 | 0 |
 2013-06 | 0002 | 0 | 0 | 0 |
 2013-07 | 0002 | 0 | 0 | 0 |

この10は販売用(2012-04)で、2は販売用(2012-02)です。

  期間| ディーラーID| チャージA| チャージB| チャージC|
 2012-06 | 0003 | 0 | 0 | 0 |
 2012-07 | 0003 | 0 | 0 | 0 |
 2012-08 | 0003 | 1 | 0 | 0 |
 2012-09 | 0003 | 0 | 0 | 0 |
 2012-10 | 0003 | 0 | 1 | 0 |
 2012-11 | 0003 | 0 | 0 | 0 |
 2012-12 | 0003 | 0 | 0 | 1 |
 2013-01 | 0003 | 0 | 0 | 0 |
 2013-02 | 0003 | 0 | 0 | 0 |
 2013-03 | 0003 | 0 | 0 | 0 |
 2013-04 | 0003 | 0 | 0 | 0 |
 2013-05 | 0003 | 0 | 0 | 0 |
 2013-06 | 0003 | 0 | 0 | 0 |
 2013-07 | 0003 | 0 | 0 | 0 |
マスターレポート

           | 2012-06 | 2012-07 | 2012-08 | 2012-09 | 2012-10 | 2012-11 |
ディーラーID| チャージA| チャージB| チャージC| チャージA| チャージB| チャージC| チャージA| チャージB| チャージC| チャージA| チャージB| チャージC| チャージA| チャージB| チャージC| チャージA| チャージB| チャージC|
001 | 0 | 0 | 0 | 0 | 0 | 0 | 100 | 0 | 0 | 18 | 0 | 0 | 0 | 100 | 0 | 0 | 18 | 0 |
002 | 0 | 10 | 2 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 |
003 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |

助けてくれてありがとう。

4

1 に答える 1

2

SQLFiddleに感謝します!それはあなたがここで達成しようとしている本当に厄介なレポートです:D

私が(まともなSQLを使用している間に)到達できる最も近いものはこれです:

SELECT
  DEALER_ID,
  DATE,
  -- Next 3 rows feature the trick to transpose lines to columns.
  SUM(IF(CHARGE = 'A', UNIT_SALES, 0)) as CHARGE_A,
  SUM(IF(CHARGE = 'B', UNIT_SALES, 0)) as CHARGE_B,
  SUM(IF(CHARGE = 'C', UNIT_SALES, 0)) as CHARGE_C
FROM (

SELECT -- Create a row for each charge A.
  DEALER_id,
  'A' as CHARGE,
  DATE_FORMAT(DATE_ADD(SALES_PERIOD, INTERVAL 2 MONTH), "%Y-%m") as DATE,
  UNIT_SALES
FROM forecasted_sales_tcl

UNION

SELECT -- Create a row for each charge B.
  DEALER_id,
  'B' as CHARGE,
  DATE_FORMAT(DATE_ADD(SALES_PERIOD, INTERVAL 4 MONTH), "%Y-%m") as DATE,
  UNIT_SALES
FROM forecasted_sales_tcl

UNION

SELECT -- Create a row for each charge C.
  DEALER_id,
  'C' as CHARGE,
  DATE_FORMAT(DATE_ADD(SALES_PERIOD, INTERVAL 6 MONTH), "%Y-%m") as DATE,
  UNIT_SALES
FROM forecasted_sales_tcl

) T
WHERE DATE >= "2012-06" AND DATE <= "2013-07"
GROUP BY DEALER_ID, DATE
ORDER BY DEALER_ID, DATE;

空の行が生成されないことを除いて、それはあなたが望むものを正確に与えます(そしてあなたの偽の出力のいくつかの間違いを指摘します:p)そしてそれは私が良識のために停止するところです。

それが不可能だとは言いませんが、それを生成するのは本当に醜いものになります。本当にやりたいのであれば、最初の(そして最も難しい)仕事は、単一の列の出力を生成するSQLクエリを作成することです。

DATE
2012-06
2012-07
2012-08
(...)
2013-06
2013-07

それはSOで尋ねるのに良い質問かもしれません:p

好奇心のために、この他のトリックを見ることができます:

SELECT @row := @row + 1 as row, t.* FROM some_table t, (SELECT @row := 0) r

とにかく、本当に空の行で出力を取得したい場合、最も簡単な方法は、別のテーブルにピリオドを入力することです。次のLEFTJOINはジョブを終了します。

マスターレポートの場合、これはまったく同じパターンです(必要に応じてサポートさせていただきます)、SQLでこれを行うことは実際にはその仕事ではないため、強くお勧めしません。転置は本当に醜く、パラメータ化できません(スペル?)。

レポートの出力に何を使用しているかわかりませんが、このビジネスに適したBIツールを確認する必要があります。メモリから、Jasper Reports、BIRT ...

さて、SQLをお楽しみください:p

于 2012-06-16T20:43:33.080 に答える