棘手的查询:预测日期

时间:2012-06-16 14:35:37

标签: mysql

美好的一天。

我在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 |

感谢您的帮助。

1 个答案:

答案 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