Salve,
se ho ben compreso, potremmo utilizzare una windowing function che "ordini con partizionamento per IdPadre", in modo che per ogni "blocco" di IdPadre le righe con Version = @n sortino per prime, seguite dalle altre, filtrando quindi poi in JOIN per la proiezione finale...
considerando una popolazione
INSERT INTO dbo.t
VALUES ( 1, 1, NULL ), ( 2, 2, NULL ), ( 3, 3, NULL ) -- tutte righe "primarie"
, ( 4, 100, NULL ), ( 5, 100, 1 ), ( 6, 100, 2 ), ( 7, 100, 3 ) -- righe "innestate"
, ( 8, 100, NULL ) -- questo per mostrare che anche il NULL First comparison non crea problematiche
;
possiamo trivialmente scrivere
DECLARE @version int = 2;
DECLARE @sortVersion int = NULL;
-- utilizzo una windowing function che ottiene un ordinamento partizionato per IdParent e poi utilizzo solo [rn] = 1
WITH cte AS (
-- t.[Version] = @version => = 1° riga ordinata, poi gli altri... SQL Server ordina NULL come "NULL First",
-- ma in ogni caso l'uguaglianza precedente porta ad un ordinamento inferiore e quindi corretto
SELECT t.Id, ROW_NUMBER() OVER (PARTITION BY t.IdParent ORDER BY
CASE WHEN
@sortVersion IS NULL THEN
-- @sortVersion == NULL, quindi la comparazione e' "secca" sulla @version
CASE WHEN t.[Version] = @version THEN 0 ELSE 1 END
ELSE
-- @sortVersion e' valorizzara, utilizzo t.[Version] == @sortVersion, per l'ordinamento principale
CASE WHEN t.[Version] = @sortVersion THEN 0 ELSE 1 END
END
) AS [rn]
FROM dbo.t t
)
SELECT t.*
FROM dbo.t t
JOIN cte c ON t.Id = c.Id
WHERE c.[rn] = 1
ORDER BY t.Id;
--<---------------------
Id IdParent Version
----------- ----------- -----------
1 1 NULL
2 2 NULL
3 3 NULL
6 100 2
si puo' valorizzare @sortVersion per la comparazione di ordinamento come desiderato.. in caso NON ci siano corrispondenze nel "gruppo" IdPadre, NULL First vince e sorta come primo elemento e, nel caso di molteplici NULL nel "gruppo", l'ordinamento e' ovviamente casuale, non abbiamo qui regola di come ordinarli...
spero di aver correttamente interpretato la richiesta
salutoni romagnoli
--
Andrea