1

Ich konnte keine Funktion finden, um zu unterstützen, was ich versuche, zu nähern.SQL Row_Number() (Partition von ... Ordnen nach ...) IGNORES Bestellanweisung

Nehmen wir an, wir die folgende Tabelle haben, die ein Feld Sortierreihenfolge und bestimmte Duplikate enthält

 
+----------+----------+-----+-------------+-----------+ 
| UniqueId | Id | Qty | RetailPrice | SortOrder | 
+----------+----------+-----+-------------+-----------+ 
|  3124 | 92361725 | 25 |  269.99 |   1 | 
|  2627 | 92361725 | 25 |  269.99 |   2 | 
|  7635 | 92361725 | 25 |  269.99 |   3 | 
|  8732 | 92361725 | 25 |  269.99 |   4 | 
|  3791 | 92361725 | 20 |  269.99 |   5 | 
|  4328 | 92361725 | 25 |  269.99 |   6 | 
+----------+----------+-----+-------------+-----------+ 

ich ihren Wert meine Zeilen zu erhöhen aufzuzählen werden soll, wenn ein Duplikat gefunden wird, wenn nicht, dann die Zeilennummer zurückgesetzt. Das Ergebnis muss in der Spalte rn gezeigt werden die folgende Tabelle, wenn Menge die Spalte zu bewerten:

 
+----------+----------+-----+-------------+-----------+----+ 
| UniqueId | Id | Qty | RetailPrice | SortOrder | rn | 
+----------+----------+-----+-------------+-----------+----+ 
|  3124 | 92361725 | 25 |  269.99 |   1 | 1 | 
|  2627 | 92361725 | 25 |  269.99 |   2 | 2 | 
|  7635 | 92361725 | 25 |  269.99 |   3 | 3 | 
|  8732 | 92361725 | 25 |  269.99 |   4 | 4 | 
|  3791 | 92361725 | 20 |  269.99 |   5 | 1 | 
|  4328 | 92361725 | 25 |  269.99 |   6 | 1 | 
+----------+----------+-----+-------------+-----------+----+ 

I ROW_NUMBER() Funktion zu nutzen versucht, aber ich kann nicht die Ergebnisse, die ich bekommen

wollen, ist
;WITH Table1 AS(
SELECT 3124 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 1 SortOrder UNION ALL 
SELECT 2627 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 2 SortOrder UNION ALL 
SELECT 7635 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 3 SortOrder UNION ALL 
SELECT 8732 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 4 SortOrder UNION ALL 
SELECT 3791 UniqueId,92361725 Id, 20 Qty, 269.99 RetailPrice, 5 SortOrder UNION ALL 
SELECT 4328 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 6 SortOrder 
) 

SELECT UniqueId, Id, Qty, RetailPrice, SortOrder, 
ROW_NUMBER() OVER (PARTITION BY Qty ORDER BY SortOrder) rn 
FROM Table1 
 
+----------+----------+-----+-------------+-----------+----+ 
| UniqueId | Id | Qty | RetailPrice | SortOrder | rn | 
+----------+----------+-----+-------------+-----------+----+ 
|  3791 | 92361725 | 20 |  269.99 |   5 | 1 | 
|  3124 | 92361725 | 25 |  269.99 |   1 | 1 | 
|  2627 | 92361725 | 25 |  269.99 |   2 | 2 | 
|  7635 | 92361725 | 25 |  269.99 |   3 | 3 | 
|  8732 | 92361725 | 25 |  269.99 |   4 | 4 | 
|  4328 | 92361725 | 25 |  269.99 |   6 | 5 | 
+----------+----------+-----+-------------+-----------+----+ 

den Auftrag durch völlig ignoriert, kann jemand helfen?

+5

Die ORDER BY wird nicht ignoriert. Wenn Sie nach Menge partitionieren, gruppieren Sie Zeile 6 mit den Zeilen 1-4. Sie müssen einen "Lücken und Inseln" -Ansatz versuchen. Sehen Sie sich die LAG-Funktion an. –

+0

Es wird überhaupt nicht ignoriert. Genau beobachten. Sie partitionieren das Ergebnis basierend auf der Spalte "Menge". Daher ist "rn" in der ersten Partition 1. Und in der nächsten Partition basiert "rn" auf "Qty". Was willst du noch? – ViKiNG

+0

Danke Tab Alleman aber leider muss dies in 2008 R2 Datenbank Engine angegangen werden, wie ich in den Tags –

Antwort

1

Hier gehen Sie. Da Sie im Jahr 2008 bin repliziert ich Lead und Lag durch selbst Beitritt dieser Tabelle auf SortOrder +/- 1. Ich aktualisierte auch Ihre Beispiel-Set für neue Inseln von Qty 25.

Sorry für die Wand des Textes, aber ich hatte Aktualisieren Sie Ihren Beispielsatz, um Island 2 Zeilen hinzuzufügen, und erstellen Sie 2 CTEs, um die Island-Bereiche zu erhalten.

--Updates Sample Set with 3 Islands. 
WITH Table1 AS(
SELECT 3124 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 1 SortOrder UNION ALL --Island 1 
SELECT 2627 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 2 SortOrder UNION ALL --Island 1 
SELECT 7635 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 3 SortOrder UNION ALL --Island 1 
SELECT 8732 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 4 SortOrder UNION ALL --Island 1 
SELECT 3791 UniqueId,92361725 Id, 20 Qty, 269.99 RetailPrice, 5 SortOrder UNION ALL --Island 2 
SELECT 4328 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 6 SortOrder UNION ALL --Island 3 
SELECT 4328 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 7 SortOrder UNION ALL --Island 3 
SELECT 4328 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 8 SortOrder   --Island 3 
), 

--Creating a CTE to get the Lead and Lag since this is 2008. This will allow us to determine if a row is the first or last row of an island. 
LeadLagTable AS(
SELECT 
    Table1.UniqueId, 
    Table1.Id, 
    Table1.Qty, 
    Table1.RetailPrice, 
    Table1.SortOrder, 
    LeadTable.SortOrder AS LeadSortOrder, 
    LagTable.SortOrder AS LagSortOrder, 
    CASE 
     WHEN LagTable.SortOrder IS NULL THEN 1 
     ELSE 0 
     END AS StartRowFlag, 
    CASE 
     WHEN LeadTable.SortOrder IS NULL THEN 1 
     ELSE 0 
     END AS LastRowFlag 
FROM Table1 
LEFT JOIN Table1 LeadTable ON 
    Table1.SortOrder = LeadTable.SortOrder - 1 
    AND Table1.Qty = LeadTable.Qty 
LEFT JOIN Table1 LagTable ON 
    Table1.SortOrder = LagTable.SortOrder + 1 
    AND Table1.Qty = LagTable.Qty 
), 

--With the LeadLagTable we can now get the ranges for each island, as well as a unique ID for each island. 
Ranges AS (
SELECT 
    RangeStart, 
    RangeEnd, 
    ROW_NUMBER() OVER (ORDER BY RangeStart) AS RangeRowNum 
FROM (
    SELECT 
     StartRow.SortOrder AS RangeStart, 
     EndRow.SortOrder RangeEnd, 
     ROW_NUMBER() OVER (PARTITION BY StartRow.SortOrder ORDER BY EndRow.SortOrder) AS rn 
    FROM LeadLagTable StartRow 
    JOIN LeadLagTable EndRow ON 
     StartRow.StartRowFlag = 1 
     AND EndRow.LastRowFlag = 1 
     AND StartRow.SortOrder <= EndRow.SortOrder 
     AND StartRow.Qty = EndRow.Qty 
    ) tbl 
WHERE rn = 1 
) 

Und hier ist die eigentliche Abfrage.

--We now join on the island ranges, and partition by the Island ID. 
SELECT 
    UniqueId, 
    Id, 
    Qty, 
    RetailPrice, 
    SortOrder, 
    ROW_NUMBER() OVER (PARTITION BY RangeRowNum ORDER BY SortOrder) AS rn 
FROM Table1 
LEFT JOIN Ranges ON 
    Table1.SortOrder >= Ranges.RangeStart 
    AND Table1.SortOrder <= Ranges.RangeEnd 
+0

Ich habe gerade festgestellt, dass dies mit den bereitgestellten Beispieldaten funktioniert, aber nicht skaliert, wenn Sie zusätzliche 25 Bestellungen mit einem gültigen Vorlauf/Nachlauf haben. Ihr rn setzt dort fort, wo der vorherige aufgehört hat. Überprüfung. –

+0

Die Antwort wurde aktualisiert. Dies sollte funktionieren, kann aber abhängig von der Tabellengröße speicherintensiv sein. –

+0

Ja, ich habe das ganze Szenario hier und passt ziemlich gut. Vielen vielen Dank für die Bemühungen –

Verwandte Themen