I have a table with 10 columns, eight of them are columns with dates. My desired outcome is to get max date for each row (what I have already accomplished) but I would also
XML has great abilities to deal with generic queries:
DECLARE @tbl TABLE(ID INT IDENTITY,d1 DATE, d2 DATE, d3 DATE);
INSERT INTO @tbl VALUES
('20180101','20180102','20180103') --one max value
,('20170101','20190102','20190102'); --two max values
SELECT TOP 1 WITH TIES
t.ID
,y.value('text()[1]','date') d
,y.value('local-name(.)','varchar(100)') c
FROM @tbl t
CROSS APPLY(SELECT d1,d2,d3 FOR XML PATH('d'),TYPE) A(x)
CROSS APPLY x.nodes('/d/*') B(y)
ORDER BY DENSE_RANK() OVER(PARTITION BY ID ORDER BY y.value('text()[1]','date') DESC);
The first CROSS APPLY
will create an XML which looks like this:
2018-01-01
2018-01-02
2018-01-03
The second CROSS APPLY
uses .nodes()
to return all nodes within
. With .value()
we can get the element's name (local-name()
) and its content.
The trick with DENSE_RANK
and TOP 1 WITH TIES
will return all rows which get a 1
(which are the highest per ID).