美好的一天。
我在SQL查询中被此问题阻止:
鉴于下表:
CREATE TABLE `Forecasted_Sales_tcl` ( `DEALER_id` varchar(15) NOT NULL, `SALES_period` date NOT NULL, `TYPE` int(2) NOT NULL, `UNIT_SALES` int(6) DEFAULT NULL, `HEAD_OFFICE_CODE` varchar(15) DEFAULT NULL PRIMARY KEY (`DEALER_CODE`,`SALES_MONTH`,`TYPE`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
http://sqlfiddle.com/#!2/b780c
我需要在未来几个月产生可能的销售费用。 例如,我已经绘制了一个月的出站销售额(unit_sales) (SALES_period)“2012年6月”在商店。我期待一些服务费 2012年8月打字A,2012年10月输入B,2012年12月输入C.我也是 在不同商店的某些不同月份有一些限制销售。
我正在尝试生成类似这样的报告:
Period |charge A | charge B |charge C | store_id 2012-Jan | X | Y | Z | (id) 2012-Feb | : | : | : : 2012-Mar | : | : | : : 2012-Apr | : | : | : : 2012-May | : | : | : : 2012-Jun | : | : | : : 2012-Jul | : | : | : : 2012-Aug | : | : | : : 2012-Sep | : | : | : : 2012-Oct | : | : | : : 2012-Nov | : | : | : : 2012-Dec | : | : | : :
X是商店的unit_sales(2个月前)的总数(id) Y是商店的unit_sales(4个月前)的总数(id) Z是商店(id)
的unit_sales(6个月前)的总和鉴于sql小提琴上的所述数据和一些参数: 生成报告: 来自:2012-06 致:2013-07
Period | Dealer Id | CHARGE X | CHARGE B | CHARGE 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 | Period | Dealer Id | CHARGE A | CHARGE B | CHARGE 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 |
On This 10适用于销售(2012-04) 2是销售(2012-02)
Period | Dealer Id | CHARGE A | CHARGE B | CHARGE 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 | Dealer ID | CHARGE A | CHARGE B | CHARGE C | CHARGE A | CHARGE B | CHARGE C | CHARGE A | CHARGE B | CHARGE C | CHARGE A | CHARGE B | CHARGE C | CHARGE A | CHARGE B | CHARGE C | CHARGE A | CHARGE B | CHARGE 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 |
感谢您的帮助。
答案 0 :(得分: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
无论如何,如果你真的想要获得空行的输出,最简单的方法是让另一个表填充句点。接下来LEFT JOIN完成工作。
对于主报告,它是完全相同的模式(如果需要,我很乐意帮助你)但我强烈反对你在SQL中这样做,因为它不是真的它工作。换位会非常难看,完全不可参数化(拼写?)。
我不知道您使用什么来输出报告,但您应该为此业务查看适当的BI工具。从记忆中,Jasper Reports,BIRT ......
好吧,享受SQL:p