2012-04-11 13 views
1

Ich habe einen Fall, wo ich nur die oberen Zeilen basierend auf einer Einstellung in einer Tabelle und der Ordnungszahl zeigen müssen.Wählen Sie obere n Datensätze basierend auf ordinal und Attributdaten

Beispieldatensatz unten zeigt zwei Kunden; Jeder Kunde hat ein anderes Produkt. Da NumRowsToShow "1" ist, möchte ich nur eine Zeile (die obere Zeile basierend auf der Ordnungszahl) für JEDEN Kunden anzeigen.

| CustomerID | ProductID | Ordinal | NumRowsToShow | 
+------------+-----------+---------+---------------+ 
| 1   |A   |1  |1    | 
| 1   |B   |2  |1    | 
| 1   |C   |3  |1    | 
| 5   |D   |1  |1    | 
| 5   |E   |2  |1    | 
| 5   |F   |3  |1    | 

Das Ergebnis nach Abfrage festgelegt wird, sollte

| CustomerID | ProductID | 
+------------+-----------+ 
| 1   |A   | 
| 5   |D   | 

Im gleichen Szenario ausgeführt werden, wenn NumRowsToShow 1 für customerID waren 1 und 2 für CustomerID 5 ich so etwas sehen würde.

| CustomerID | ProductID | Ordinal | NumRowsToShow | 
+------------+-----------+---------+---------------+ 
| 1   |A   |1  |1    | 
| 1   |B   |2  |1    | 
| 1   |C   |3  |1    | 
| 5   |D   |1  |2    | 
| 5   |E   |2  |2    | 
| 5   |F   |3  |2    | 

Das Ergebnis nach Abfrage festgelegt wird, sollte dies getan werden Wie kann

| CustomerID | ProductID | 
+------------+-----------+ 
| 1   |A   | 
| 5   |D   | 
| 5   |E   | 

sein laufen?

Einschließlich einer Bildschirmkappe des tatsächlichen Ergebnisses mit Highlights von dem, was ich versuche zu filtern, was ein wenig hilfreich sein kann.

Screencap http://www.harpernet.net/se/cap01.jpg

+1

Und was passiert, wenn ein Reihen des Kunden hatten drei verschiedene 'NumRowsToShow' (zB 1,2,3) –

+0

Das würde nicht passieren; NumRowsToShow kommt von einer Einstellung pro CustomerID. Es ist das gleiche. Dies ist ein Ergebnis mehrerer Abfragen. Kunde/ProductID sind nicht die tatsächlichen Ergebnissätze. Ich versuche nur, ein einfaches Beispiel dafür zu geben, was ich filtere. – sugarcrum

Antwort

6

Es fühlt sich an wie "in den Prüfungen Betrug":

SELECT CustomerID, ProductID 
FROM tableX 
WHERE Ordinal <= NumRowsToShow 

Wenn, wie Kommentare vorschlagen, die Ordinal10, 20, 30 Werte haben kann und nicht nur 1, ..., n Werte, dann wird diese Arbeit:

SELECT t.CustomerID, t.ProductID 
FROM tableX AS t 
    JOIN tableX AS tt 
    ON tt.CustomerID = t.CustomerID 
    AND tt.Ordinal <= t.Ordinal 
GROUP BY t.CustomerID 
     , t.ProductID 
     , t.NumRowsToShow 
HAVING COUNT(*) <= t.NumRowsToShow 

oder noch besser, die:

SELECT CustomerID, ProductID 
FROM 
    (SELECT CustomerID, ProductID, NumRowsToShow 
     , ROW_NUMBER() OVER(PARTITION BY CustomerID 
           ORDER BY Ordinal 
          ) AS Rn 
    FROM tableX 
) AS tmp 
WHERE Rn <= NumRowsToShow ; 

-Test in: SQL-Fiddle


Ihre Tabelle sieht nicht normalisiert werden. Die NumRowsToShow Spalten haben doppelte Informationen und das kann dazu führen, dass Anomalien aktualisiert werden. Dies:

| CustomerID | ProductID | Ordinal | 
+------------+-----------+---------+ 
| 1   |A   |1  | 
| 1   |B   |2  | 
| 1   |C   |3  | 
| 5   |D   |1  | 
| 5   |E   |2  | 
| 5   |F   |3  | 

und:

| CustomerID | ProductID | Ordinal | NumRowsToShow | 
+------------+-----------+---------+---------------+ 
| 1   |A   |1  |1    | 
| 1   |B   |2  |1    | 
| 1   |C   |3  |1    | 
| 5   |D   |1  |2    | 
| 5   |E   |2  |2    | 
| 5   |F   |3  |2    | 

konnte auf 2 Tabellen normalisiert werden

| CustomerID | NumRowsToShow | 
+------------+---------------+ 
| 1   |1    | 
| 5   |2    | 
+0

Die Tabelle ist das Ergebnis einer anderen Abfrage. Dies wird nur als ein einfaches Beispiel für den resultierenden Datensatz verwendet, den ich zu filtern versuche. Ich mag den einfachen Ansatz von Ordinal <= NumRowsToShow. Es funktioniert fast, mit der Ausnahme, dass "Ordinal" 10, 20, 30 sein kann. Muss nicht 1, 2,3 sein. – sugarcrum

+0

Vielen Dank für die Zeit bis zur Antwort. Die Partition-Anweisung ist genau das, wonach ich gesucht habe. Ich ging diese Straße hinunter, konnte aber nicht den richtigen Weg finden, sie zu strukturieren. Sehr, sehr geschätzt für die Hilfe. – sugarcrum

Verwandte Themen