2016-04-13 5 views
2

TabellenschemaWie ROLLUP- RANK() mit Pivot-Tabelle in Oracle11g

CREATE TABLE customer ( 
id   NUMERIC, 
lname  VARCHAR (30), 
fname  VARCHAR (30) NOT NULL, 
street  VARCHAR (30) NOT NULL, 
city  VARCHAR (30) NOT NULL, 
zipcode  NUMERIC (5) NOT NULL, 
state  VARCHAR (2) NOT NULL, 
phone  VARCHAR (12) NOT NULL, 
creditscore NUMERIC, 
credit_org VARCHAR (30), 
cs_date  DATE, 
CONSTRAINT customer_pk PRIMARY KEY (id) 
); 

Anforderung verwenden:

Teil 1: erstellen eine Pivot-Tabelle die Anzahl der Kunden nach Ort zur Liste ('PA ',' CA ',' NY ',' MD ') und auch nach creditscore range. Für creditscore Bereich, erstellen Sie 3 Segmente, "LOWER RANGE (500-600)" definiert als diejenigen mit Kredit-Score zwischen 500-600, "AVERAGE RANGE (600-700)" definiert als diejenigen mit Kredit-Score zwischen 600-700, 'PREMIUM RANGE (700+) 'definiert als solche mit einem Kredit-Score von 700+. Das Ergebnis der Pivot-Tabelle sollte 4 Spalten für Status und 3 Zeilen für den Creditscore-Bereich enthalten.

Teil 2: Fügen Sie eine Gesamtreihe hinzu, um die Gesamtzahl der Kunden für die jeweiligen Bundesstaaten anzugeben. Rangieren Sie die Bundesstaaten basierend auf der Gesamtzahl der Kunden.

Zusätzliche Anforderung Rangieren Sie die Staaten basierend auf der Gesamtzahl der Kunden zuerst im Premium-Bereich, dann durchschnittliche Reichweite und dann niedrigere Reichweite.

Meine Meinung Bisher

SELECT * FROM (
    SELECT case 
      when CREDITSCORE between 500 and 600 then 'LOWER RANGE(500-600)' 
      when CREDITSCORE <= 700 then 'AVERAGE RANGE(600-700)' 
      else 'PREMIUM RANGE(700+)' 
    end as CREDITSCORE_RANGE, 
    state 
    FROM customer 
) 
PIVOT (
    count(state) FOR state IN ('PA', 'CA', 'NY', 'MD') 
); 

Es ist richtig, zum Teil 1

Meine Frage ist, wie Teil 2 in Angriff zu nehmen und Ist es überhaupt möglich?

Edit 1:

MY oben unter Verwendung von DECODE

SELECT DECODE (Fall nehmen, wenn Kreditscoring < = 600 dann 'LOWER RANGE (500-600)' wenn Kreditscoring < = 700 dann ‚AVERAGE RANGE (600-700)‘ else 'premium RANGE (700+)' Ende, NULL, 'Total', Fall wenn Kreditscoring zwischen 500 und 600 dann 'LOWER RANGE (500-600)' wenn Kreditscoring < = 700 dann 'DURCHSCHNITTLICHE BEREICH (600-700)' sonst 'PREMIUM RANGE (700+)' Ende) "CREDITSCORE_RANGE", SUM (DECODE (Zustand, 'PA', 1, 0)) "Pennsylvania", SUM (DECODE (Zustand, 'CA', 1, 0)) "California", SUMME (DECODE (Zustand, 'NY', 1, 0)) "New York", SUMME (DECODE (Zustand, 'MD', 1, 0)) "Maryland", zählen (Kreditscoring) "gesamte Anzahl der Kunden," RANK() OVER (ORDER BY Count (Kreditscoring) DESC) "RANK durch NO oF CUSTOMERS" FROM Kunden GROUP BY ROLLUP- (Fall wenn Kreditscoring zwischen 500 und 600 dann ‚LOWER BEREICH (500-600) ' wenn CREDITSCORE < = 700 dann' DURCHSCHNITTLICHE BEREICH (600-700) ' sonst' PREMIUM BEREICH (700+) ' Ende);

Antwort

1

Ich glaube nicht, dass Ihre Bereiche für die Frage, die Sie geschrieben haben, recht sind, obwohl der Wortlaut der Zuordnung zweideutig ist, da "zwischen" inklusive ist - so wie die Frage formuliert ist, ein Kredit-Score von genau 600 würde sowohl in der unteren als auch in der mittleren Klammer erscheinen. Ihre Version wird 600 in die "untere" Klammer setzen, aber es ist strittig, in welcher sie sein sollte; Ich würde denken, dass es von den anderen Definitionen "durchschnittlich" sein sollte, aber es ist unklar. Es gibt keine Klammer in der Frage für Punkte weniger als 500, aber wenn Sie irgendwelche von denen dann haben, schließt Ihr gegenwärtiger Code sie in die "durchschnittliche" Klammer ein, da sie weniger als 700 aber nicht zwischen 500 und 600 sind.

So hätte ich interpretiert, dass als:

SELECT * FROM (
    SELECT case 
      when CREDITSCORE >= 500 and CREDITSCORE < 600 then 'LOWER RANGE(500-600)' 
      when CREDITSCORE >= 600 and CREDITSCORE < 700 then 'AVERAGE RANGE(600-700)' 
      when CREDITSCORE >= 700 then 'PREMIUM RANGE(700+)' 
    end as CREDITSCORE_RANGE, 
    state 
    FROM customer 
) 
PIVOT (
    count(state) FOR state IN ('PA' as pa, 'CA' as ca, 'NY' as ny, 'MD' as md) 
); 

Ihre Frage Titel ROLLUP- bezieht, und die gesamte Reihe bekommen können Sie diese Funktion verwenden:

SELECT creditscore_range, sum(pa) AS pa, sum(ca) AS ca, sum(ny) AS ny, sum(md) AS md 
FROM (
    SELECT * FROM (
    SELECT CASE 
      WHEN creditscore >= 500 AND creditscore < 600 THEN 'LOWER RANGE(500-600)' 
      WHEN creditscore >= 600 AND creditscore < 700 THEN 'AVERAGE RANGE(600-700)' 
      WHEN creditscore >= 700 THEN 'PREMIUM RANGE(700+)' 
     END AS creditscore_range, 
     state 
    FROM customer 
) 
    PIVOT (
    COUNT(state) FOR state IN ('PA' AS pa, 'CA' AS ca, 'NY' AS ny, 'MD' AS md) 
) 
) 
GROUP BY ROLLUP (creditscore_range); 

Wenn Sie tun alle Werte unter 500, dann wird Both eine Zeile für diejenigen mit der creditscore_range als Null enthalten; was mit der ROLLUP Version verwirrend ist. Möglicherweise möchten Sie alle Scores von weniger als 500 aus der innersten Abfrage filtern, aber auch hier ist nicht klar, ob dies notwendig oder wünschenswert ist.

Ich bin mir nicht sicher, dass die Aufgabe suchen, wenn es um Ranking geht. Das bedeutet, dass die Spaltenreihenfolge basierend auf den darin enthaltenen Werten geändert werden muss. Eine Rangfolge nach Staat würde mehr Sinn ergeben, wenn die Daten umgekehrt gedreht würden.

+0

Vielen Dank für Ihre Antwort. Und Beispieldaten haben keinen Creditscore <500, aber es ist sinnvoll, die Bereiche wie vorgeschlagen zu ändern. Ich habe einen Versuch durch DECODE gemacht. Ich setze es mit der Bearbeitung. Aber ich werde Sie fragen, ob Sie eine Lösung bereitstellen können, indem Sie wie vorgeschlagen einen anderen Weg einschlagen. Es macht mehr Sinn, aber ich bin mir nicht sicher, wie ich es angehen soll. Vielen Dank –