2012-06-16 8 views
5

Buen día.Tricky Query: Fechas de pronóstico

estoy bloqueado por este problema en mi consulta SQL:

Dada la siguiente tabla:

 
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

necesito para generar los posibles cargos de venta en los próximos meses. Por ejemplo, tracé una venta saliente (ventas_unidades) durante un mes (período_SALES) "junio de 2012" en una tienda. Estoy esperando algunos cargos por servicio tipo A en agosto de 2012, tipo B en octubre de 2012, tipo C en diciembre de 2012. También tengo con algunas ventas consolidadas en algunos meses diferentes en tiendas diferentes.

Estoy tratando de generar un informe de algo como esto:

 
    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 es total los unit_sales (2 meses) para la tienda (id) Y es total los unit_sales (4 meses) para la tienda (id) Z es total los unit_sales (hace 6 meses) para la tienda (id)


Dadas dichos datos SQL en el violín y algunos parámetros: generar el informe: Desde: 2012- 06 Para : 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 | 

En esta 10 es para las ventas (2012-04), mientras que 2 es para las ventas (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 | 
Informe Maestro

 

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

Gracias por la ayuda.

+2

Hum ... eso es bastante complicado y estoy teniendo un poco de un dolor de cabeza tratando de entender correctamente la pregunta. Pero parece interesante, ¿podría crear un [sqlfiddle] (http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CFAQFjAA&url=http%3A%2F% 2Fsqlfiddle.com% 2F & ei = 5JvcT5bCIbCM0wWxg8jNCg & usg = AFQjCNFm12TxaUOyr1fCpsH3njbgA9q20A) con algunos datos y agrega un resultado esperado? –

Respuesta

2

¡Muchas gracias por el SQLFiddle! Es un informe realmente desagradable que estamos tratando de lograr aquí: D

Lo más cerca que puedo llegar a (durante el uso de SQL decente) es la siguiente:

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; 

Eso le da exactamente lo que quiere (y señale algunos errores en su salida falsa por cierto: p) excepto que no genera las filas vacías y ahí es donde me detengo por la decencia.

No digo que no sea posible pero se vuelve realmente feo lo genera.Si realmente quiere entrar en ella, la primera (y más difícil) trabajo es escribir una consulta SQL que genera una única salida de la columna:

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

que podría ser una buena pregunta para preguntar sobre SO: p

Por el amor curiosidad que podría echar un vistazo a este otro truco:

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

de todos modos, si usted realmente desea conseguir que la salida de las filas vacías, la forma más sencilla es tener otra mesa llena de los períodos . Siguiente LEFT JOIN finaliza el trabajo.

Para el Informe maestro, es exactamente el mismo patrón (y estaré encantado de ayudarlo si es necesario) pero Le recomiendo encarecidamente que haga esto en SQL, ya que no es realmente su trabajo. La transposición será realmente fea, y completamente no parametrizable (¿deletreo?).

No sé lo que está utilizando para publicar el informe, pero debe consultar las herramientas de BI adecuadas para este negocio. De memoria, Jasper Reports, BIRT ...

Bueno, disfrutar de SQL: p

+0

Muchas gracias por la respuesta, daré retroalimentación el lunes =). De nuevo, mi sincero agradecimiento. –

+0

Esto es muy útil =) –