2012-06-16 11 views
5

Dzień dobry.Tricky Query: Prognozy Daty

jestem zablokowany przez tego problemu w moim zapytaniu SQL:

Given poniższej tabeli:

 
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

muszę generować ewentualne opłaty sprzedaży w najbliższych miesiącach. Na przykład zaplanowałem sprzedaż wychodzącą (unit_sales) na miesiąc (SALES_period) "June 2012" w sklepie. Oczekuję pewnych opłat za usługi typu A w sierpniu 2012 r., Typ B w październiku 2012 r., Typ C w grudniu 2012 r. Również mają pewne wyprzedaże w różnych miesiącach w różnych sklepach.

Próbuję wygenerować raport coś takiego:

 
    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 oznacza sumie unit_sales (2 miesiące temu) dla magazynu (ID) Y jest sumie unit_sales (4 miesiące temu) do sklep (id) z jest sumie unit_sales (6 miesięcy temu) dla magazynu (ID)


Biorąc pod uwagę wspomniane dane na temat sql skrzypce i niektóre parametry: wygenerować raport: Od: 2012- 06 Do: 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 | 

Na tej 10 jest dla Sprzedaż (2012-04), podczas gdy 2 jest dla sprzedaży (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 | 
Mistrza Raportu

 

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

Dzięki za pomoc.

+2

Hum ... to dość trudne i mam trochę ból głowy próbując zrozumieć poprawnie na pytanie. Ale wygląda na interesującą, możesz utworzyć [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) z niektórymi danymi i dodać oczekiwany wynik? –

Odpowiedz

2

Wielkie dzięki za SQLFiddle! Jest to raport naprawdę paskudny starasz się osiągnąć tutaj: D

Najbliżej mogę dostać się do (podczas korzystania godnej SQL) jest taka:

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; 

który daje dokładnie to, co chcesz (i wskazuj na błędy w twoim fałszywym wyniku: p), ale nie generuje on pustych wierszy i tam właśnie zatrzymuję się dla przyzwoitości.

Nie mówię, że nie jest to możliwe, ale staje się naprawdę brzydkie dla generowania go.Jeśli naprawdę chcesz, aby dostać się do niego, pierwszy (i najtrudniejsze) zadaniem jest napisać zapytanie SQL, który generuje pojedyncze wyjście kolumna:

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

które mogłyby być miłym pytaniem na SO: p

na litość ciekawości można rzucić okiem na ten inny trick:

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

w każdym razie, jeśli naprawdę chcesz, aby uzyskać ouput z pustych wierszy, najprostszym sposobem jest już inna tabela wypełniona okresach . Dalej LEFT JOIN kończy pracę.

Dla poinformuj Master jest dokładnie taki sam wzór (i będę zadowolony, aby pomóc jej w razie potrzeby) ale zdecydowanie zniechęcają cię od robienia tego w SQL, jak to naprawdę nie jest jego praca. Transpozycja będzie naprawdę brzydka i nie będzie parametryzowalna (pisownia?).

Nie wiem, czego używasz do ouput raportu, ale powinieneś spojrzeć na odpowiednie narzędzia BI dla tej firmy. Z pamięci, Jasper Reports, BIRT ...

Well, cieszyć SQL: p

+0

Bardzo dziękuję za odpowiedź, udzielę informacji zwrotnej do poniedziałku =). Ponownie, moje szczere podziękowania. –

+0

Jest to bardzo przydatne =) –