hobby:development:sql:select:query_0001

Auto self-join per raggruppare in base ad un criterio Vai alla mappa
(Come eseguire un self join per filtrare il raggruppamento ottenuto)

Il problema in analisi è quello che si presenta ogni volta che si vuole ottenere l'ultima versione del dato di una determinata anagrafica.
Un esempio molto semplice potrà far capire meglio di tante spiegazioni

Serviamoci della seguente tabella di esempio:

USE DbTemp

IF OBJECT_ID(N'dbo.tblHistory', 'U') IS NOT NULL
	DROP TABLE dbo.tblHistory

-- Create table [dbo].[tblHistory]
PRINT (N'Create table [dbo].[tblHistory]')

CREATE TABLE dbo.tblHistory (
	 IdHistory INT NULL DEFAULT (0)
	,IdData int NULL DEFAULT (0)
	,Description varchar(50) NULL DEFAULT ('')
)
ON [PRIMARY]

che andremo a popolare con pochi dati ma sufficienti per capire

INSERT INTO dbo.tblHistory (IdHistory, IdData, Description) VALUES
 	 (1,  1, 'Descrizione primo record')
	,(2,  1, 'Descrizione primo record prima modifica')
	,(3,  1, 'Descrizione primo record ultima modifica')
	,(4,  2, 'Descrizione secondo record')
	,(5,  2, 'Descrizione secondo record prima modifica')
	,(6,  2, 'Descrizione secondo record ultima modifica')
	,(7,  3, 'Descrizione terzo record')
	,(8,  3, 'Descrizione terzo record ultima modifica')
	,(9,  4, 'Descrizione quarto record')
	,(10, 4, 'Descrizione quarto record ultima modifica')

quindi con una semplice select otterremo:

SELECT * FROM dbo.tblHistory;

IdHistoryIdDataDescription
11Descrizione primo record
21Descrizione primo record prima modifica
31Descrizione primo record ultima modifica
42Descrizione secondo record
52Descrizione secondo record prima modifica
62Descrizione secondo record ultima modifica
73Descrizione terzo record
83Descrizione terzo record ultima modifica
94Descrizione quarto record
104Descrizione quarto record ultima modifica

Tramite la colonna IdData possiamo identificare tutte le revisioni di un anagrafica, ma l'obbiettivo è quello di estrarre solo le anagrafiche nell'ultima versione, cioè quelle che a pari valore di IdData hanno IdHistory maggiore.

La soluzione è relativamente semplice e consiste nel ricorrere ad un self-join come quello che segue:

SELECT 
	tblA.*
FROM tblHistory tblA
	LEFT JOIN tblHistory tblB ON tblA.IdData = tblB.IdData AND tblA.IdHistory < tblB.IdHistory
WHERE tblB.IdHistory IS NULL

IdHistoryIdDataDescription
31Descrizione primo record ultima modifica
62Descrizione secondo record ultima modifica
83Descrizione terzo record ultima modifica
104Descrizione quarto record ultima modifica
  • hobby/development/sql/select/query_0001.txt
  • Ultima modifica: 2021/01/04 12:35
  • da mauro.cortese