2017-02-15 3 views
1

Ich habe eine Abfrage, die eingehende Zahlungen in Datumsbereiche (1-7 Tage, 3-6 Monate etc.) und es gruppiert weitgehend funktioniert, wie ich es mir erhofft hatte. Ich möchte jedoch eine Zeile mit 0 zurückgeben, wenn im Datumsbereich kein Einkommen erwartet wird.Abfrage mit CASE-Anweisung in Group By Ich muss einen Eintrag erstellen, wo keine Ergebnisse in der WHEN

Die Gruppe durch sieht wie folgt aus:

group by 

CASE WHEN timestampdiff(day,curdate(),data.duedate) between 0 and 7 then 1 
     WHEN timestampdiff(day,curdate(),data.duedate) between 8 and 14 then 2 
     WHEN timestampdiff(day,curdate(),data.duedate) between 15 and 30 then 3 
     WHEN timestampdiff(month,curdate(),data.duedate) between 1 and 2 then 4 
     WHEN timestampdiff(month,curdate(),data.duedate) between 2 and 3 then 5 
     WHEN timestampdiff(month,curdate(),data.duedate) between 3 and 6 then 6 
     WHEN timestampdiff(month,curdate(),data.duedate) between 6 and 12 then 7 
     WHEN timestampdiff(year,curdate(),data.duedate) between 1 and 2 then 8 
     WHEN timestampdiff(year,curdate(),data.duedate) between 2 and 3 then 9 
     WHEN timestampdiff(year,curdate(),data.duedate) between 3 and 4 then 10 
     WHEN timestampdiff(year,curdate(),data.duedate) between 5 and 6 then 11 
     WHEN timestampdiff(year,curdate(),data.duedate) >= 7 then 12 

Das funktioniert richtig, dass es gibt mir die richtigen Mengen, aber ich möchte den Code zwingen, mir zu geben eine 0, so dass zur Zeit das ich erhalten:

1 300000 
5 150000 
8 300000 

Was ich wirklich will, ist dies:

1 300000 
2 0 
3 0 
4 0 
5 150000 
6 0 
7 0 
8 300000 
etc. 

Dies ist die gesamte Abfrage - ich habe versucht, eine mit n IFNULL() aber hatte keinen Erfolg:

select 

sum(data.principaldue+data.interestdue) as m 

from 
(select 
    la.id 
    ,rep.duedate 
    ,rep.PRINCIPALDUE 
    ,rep.INTERESTDUE 
    from repayment rep 
    join loanaccount la on la.ENCODEDKEY = rep.PARENTACCOUNTKEY 
    join loanproduct lp on lp.ENCODEDKEY = la.PRODUCTTYPEKEY 

group by 

CASE WHEN timestampdiff(day,curdate(),data.duedate) between 0 and 7 then 1 
     WHEN timestampdiff(day,curdate(),data.duedate) between 8 and 14 then 2 
     WHEN timestampdiff(day,curdate(),data.duedate) between 15 and 30 then 3 
     WHEN timestampdiff(month,curdate(),data.duedate) between 1 and 2 then 4 
     WHEN timestampdiff(month,curdate(),data.duedate) between 2 and 3 then 5 
     WHEN timestampdiff(month,curdate(),data.duedate) between 3 and 6 then 6 
     WHEN timestampdiff(month,curdate(),data.duedate) between 6 and 12 then 7 
     WHEN timestampdiff(year,curdate(),data.duedate) between 1 and 2 then 8 
     WHEN timestampdiff(year,curdate(),data.duedate) between 2 and 3 then 9 
     WHEN timestampdiff(year,curdate(),data.duedate) between 3 and 4 then 10 
     WHEN timestampdiff(year,curdate(),data.duedate) between 5 and 6 then 11 
     WHEN timestampdiff(year,curdate(),data.duedate) >= 7 then 12 

END 

Order by 

CASE WHEN timestampdiff(day,curdate(),data.duedate) between 0 and 7 then 1 
     WHEN timestampdiff(day,curdate(),data.duedate) between 8 and 14 then 2 
     WHEN timestampdiff(day,curdate(),data.duedate) between 15 and 30 then 3 
     WHEN timestampdiff(month,curdate(),data.duedate) between 1 and 2 then 4 
     WHEN timestampdiff(month,curdate(),data.duedate) between 2 and 3 then 5 
     WHEN timestampdiff(month,curdate(),data.duedate) between 3 and 6 then 6 
     WHEN timestampdiff(month,curdate(),data.duedate) between 6 and 12 then 7 
     WHEN timestampdiff(year,curdate(),data.duedate) between 1 and 2 then 8 
     WHEN timestampdiff(year,curdate(),data.duedate) between 2 and 3 then 9 
     WHEN timestampdiff(year,curdate(),data.duedate) between 3 and 4 then 10 
     WHEN timestampdiff(year,curdate(),data.duedate) between 5 and 6 then 11 
     WHEN timestampdiff(year,curdate(),data.duedate) >= 7 then 12 

END 
+0

Sie könnten Recht beitreten es mit einer Nummerentabelle? – user5226582

+0

Leider habe ich in diesem Schema keine Nummerntabelle und ich habe auch keine Berechtigung, Tabellen zu erstellen. – monkeyb33f

+0

Verwenden Sie eine Tabellenvariable dafür. – user5226582

Antwort

1

Dies ist keine vollständige Antwort, wäre aber zu groß für Kommentare;

Eine temporäre Tabelle mit Zahlen könnte nützlich sein:

MySql temporary tables:

CREATE TEMPORARY TABLE TempTable (num int); 
INSERT INTO TmpTable VALUES(1,2,3,4,5,6,7,8,9,10,11,12 ...); 

Dann könnten Sie rechts auf dieser Tabelle beitreten werden, um sicherzustellen, fehlende Werte enthalten.

Können sagen, Sie haben dies:

results(num, val): 
1 300000 
5 150000 
8 300000 

Diese in der gewünschten Ausgabe zur Folge haben sollte:

SELECT numbers.num, COALESCE(results.val, 0) as val 
FROM results RIGHT JOIN TempTable numbers on results.num = numbers.num 
WHERE numbers.num <= 12 --or other max number 

1 300000 
2 0 
... 
5 150000 
... 

Hoffnung, das hilft.

Edit:

Wenn Sie keine Berechtigung, temporäre Tabellen erstellen verfügen, suchen Sie nach einer Abhilfe aufeinanderfolgenden ganzen Zahlen zu wählen, for example:

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

Wo some_table ist jede Tabelle mit genügend Zeilen .

Verwenden Sie wahrscheinlich ein Top N auf diesem.

Eine andere schmutzige Problem zu umgehen, könnte gut genug sein, wenn Sie viele Zahlen müssen nicht:

SELECT 1 num 
UNION 
SELECT 2 num 
UNION 
... 

Edit:

etwas aufgeräumter Abhilfe:

SELECT * FROM (VALUES (1), (2), (3), ...) x(i) 
+0

Hallo - danke für Ihre Antwort, aber ich habe Angst, ich habe nicht die entsprechenden Berechtigungen, um temporäre Tabellen im Schema zu erstellen. – monkeyb33f

+0

Ich habe deinen Kommentar erst gesehen, nachdem ich diesen Beitrag gepostet habe. Wird die Antwort aktualisieren, wenn an etwas anderes denken kann. – user5226582

+0

Aktualisierung durchgeführt. – user5226582