Performance
Readability
Self-joins are frequently used to perform inter row calculations to look forward or backward across row boundaries in a table.
Self joins increase the number of records fetched and the number of table scans
Self-joins are hard to read and understand for most SQL developers in particular if they contain non-equi joins
Self-joins can be hard to debug
Here is an example of a self-join using a non-equi join condition (>).
SELECT wv1.vehicleregistration
,wv1.chillersensornumber
,wv1.recordedwhen
,MAX(wv2.recordedwhen) AS previous_recordedwhen
,DATEDIFF('second'
,MAX(wv2.recordedwhen)
,wv1.recordedwhen) AS TIME_ELAPSED
FROM warehouse_vehicletemperatures wv1
LEFT
JOIN warehouse_vehicletemperatures wv2
ON wv1.vehicleregistration=wv2.vehicleregistration
AND wv1.chillersensornumber=wv2.chillersensornumber
AND wv1.recordedwhen>wv2.recordedwhen
GROUP BY wv1.vehicleregistration
,wv1.chillersensornumber
,wv1.recordedwhen;
Most self joins can be replaced by using window functions.
Window functions generally do not suffer from the issues of self-joins
SELECT vehicleregistration
,chillersensornumber
,recordedwhen
,LAG(recordedwhen) OVER(PARTITION BY vehicleregistration
,chillersensornumber
ORDER BY recordedwhen) AS previous_recordedwhen
,DATEDIFF('second'
,LAG(recordedwhen) OVER(PARTITION BY vehicleregistration
,chillersensornumber
ORDER BY recordedwhen)
,recordedwhen) AS TIME_ELAPSED
FROM warehouse_vehicletemperatures;
In rare cases a self-join can be more performant than a window function. The more of the following conditions your query meets, the more efficiently the window function will operate compared to the self join.
Most of the time, it’s a good idea to run a performance test to compare how well the query with the self-join works to how well the window function works.