CREATE FUNCTION dbo.GetMeasurementChanges -- always use schema prefix ( @ObjectID INT, @AttributeName VARCHAR(32) ) RETURNS TABLE -- use an inline table-valued function when possible WITH SCHEMABINDING AS RETURN ( WITH x AS ( SELECT ObjectID, MeasurementID, Attribute1, Attribute2, Attribute3, rn = ROW_NUMBER() OVER (ORDER BY MeasurementID) FROM dbo.MyTable -- update this of course WHERE ObjectID = @ObjectID ), y AS ( SELECT MeasurementID, r1 = CASE @AttributeName WHEN 'Attribute1' THEN ROW_NUMBER() OVER (PARTITION BY Attribute1 ORDER BY MeasurementID) END, r2 = CASE @AttributeName WHEN 'Attribute2' THEN ROW_NUMBER() OVER (PARTITION BY Attribute2 ORDER BY MeasurementID) END, r3 = CASE @AttributeName WHEN 'Attribute3' THEN ROW_NUMBER() OVER (PARTITION BY Attribute3 ORDER BY MeasurementID) END FROM x ) SELECT MeasurementID FROM y WHERE 1 IN (r1, r2, r3) AND NOT EXISTS ( SELECT 1 FROM x WHERE x.rn = 1 AND MeasurementID = y.MeasurementID ) ); GO
Alternative:
CREATE FUNCTION dbo.GetMeasurementChanges -- always use schema prefix ( @ObjectID INT, @AttributeName VARCHAR(32) ) RETURNS TABLE -- use an inline table-valued function when possible WITH SCHEMABINDING AS RETURN ( WITH x AS ( SELECT ObjectID, MeasurementID, Attribute1, Attribute2, Attribute3, rn = ROW_NUMBER() OVER (ORDER BY MeasurementID) FROM dbo.MyTable WHERE ObjectID = @ObjectID ), y AS ( SELECT MeasurementID, r = ROW_NUMBER() OVER ( PARTITION BY CASE @AttributeName WHEN 'Attribute1' THEN Attribute1 WHEN 'Attribute2' THEN CONVERT(VARCHAR(32), Attribute2) WHEN 'Attribute3' THEN Attribute3 END ORDER BY MeasurementID) FROM x ) SELECT MeasurementID FROM y WHERE r = 1 AND NOT EXISTS ( SELECT 1 FROM x WHERE x.rn = 1 AND MeasurementID = y.MeasurementID ) ); GO
source share