sql >> Databasteknik >  >> RDS >> Sqlserver

Sortering baserat på nästa och tidigare poster i SQL

Du kan göra något sånt här.

  1. Identifiera första och sista bokstaven för varje förälder genom att använda ROW_NUMBER() och PARTITION BY
  2. Matcha den sista posten i föregående ids med den första posten för nästa ids .
  3. Kontrollera om det andra föräldra-id:t har någon bokstav som matchar bokstaven som valts ovan
  4. Använd en LEFT JOIN och använd CASE eller ISNULL för att ställa in en högre prioritet för ett sådant ids post där bokstaven hade matchat

Fråga

;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 

Utdata

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

SQL Fiddle

REDIGERA

Om dina ids inte är sekventiella kan du ändra CTE1 och CTE2 så här för att använda ROW_NUMBER()OVER(ORDER BY ID) seq_id .

;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
)

Resten av koden förblir densamma.

SQL-fiol




  1. Filtrera mellan två datum MYSQL

  2. Slå samman två tabeller i SQL Server 2008

  3. Anpassad aggregatfunktion i PostgreSQL

  4. Oracle Forms i R12/R12.2