Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Sortieren basierend auf den nächsten und vorherigen Datensätzen in SQL

Sie können so etwas tun.

  1. Identifizieren Sie den ersten und letzten Buchstaben jedes Elternteils mit ROW_NUMBER() und PARTITION BY
  2. Übereinstimmung mit dem letzten Datensatz der vorhergehenden id mit dem ersten Datensatz der nächsten id .
  3. Überprüfen Sie, ob die zweite übergeordnete ID einen Buchstaben hat, der mit dem oben ausgewählten Buchstaben übereinstimmt
  4. Verwenden Sie einen LEFT JOIN und verwenden Sie CASE oder ISNULL um eine höhere Priorität für eine solche id festzulegen Datensatz, in dem der Buchstabe übereinstimmte

Abfrage

;WITH CTE AS 
(
SELECT id,ParentID,letter,
ROW_NUMBER()OVER(PARTITION BY parentId ORDER BY ID) first_element,
ROW_NUMBER()OVER(PARTITION BY parentId ORDER BY ID DESC) Last_element
FROM Child
), CTE2 AS 
(
SELECT c1.id,c1.parentid,c1.letter,c2.parentid as c2parentid
FROM CTE c1
INNER JOIN CTE c2
ON c1.last_element = 1
AND c2.first_element = 1
AND c1.id +1 = c2.id
), CTE3 AS 
(
SELECT C.parentid,C.id
FROM CTE2
INNER JOIN child C ON CTE2.c2parentid = C.parentid
AND C.letter = CTE2.letter
)
SELECT P.number, C.letter
FROM Child C
JOIN Parent P ON C.parentId = P.id
LEFT JOIN CTE3 ON CTE3.id = C.id
ORDER BY P.number, ISNULL(CTE3.id,0) DESC, C.letter 

Ausgabe

number  letter
1   A
1   C
2   C
2   B
3   B
3   D

SQL-Geige

BEARBEITEN

Wenn Ihre ids nicht sequentiell sind, können Sie CTE1 ändern und CTE2 so, um ROW_NUMBER()OVER(ORDER BY ID) seq_id zu verwenden .

;WITH CTE AS 
(
SELECT id,ParentID,letter,
ROW_NUMBER()OVER(ORDER BY ID) seq_id,
ROW_NUMBER()OVER(PARTITION BY parentId ORDER BY ID) first_element,
ROW_NUMBER()OVER(PARTITION BY parentId ORDER BY ID DESC) Last_element
FROM Child
), CTE2 AS 
(
SELECT c1.id,c1.parentid,c1.letter,c2.parentid as c2parentid
FROM CTE c1
INNER JOIN CTE c2
ON c1.last_element = 1
AND c2.first_element = 1
AND c1.seq_id + 1 = c2.seq_id
)

Der Rest des Codes bleibt gleich.

SQL-Geige