Следующее сделает свое дело, но в ответ на ответ я хочу, чтобы вы отправили Google «рекурсию» и посмотрите, что Google предлагает для поиска:)
Уточнение: рекурсия происходит путем объединения строки - 1 в строку между временной таблицей и CTE. Этот метод зависит от наличия независимого столбца IDENTITY
(в данном случае ID
) и использует ROWNUMBER()
для учета любых возможных пробелов в идентификаторах. Поскольку ROW_NUMBER()
нельзя использовать в JOIN
, мне пришлось прибегнуть к использованию подзапроса в рекурсивной части CTE
. Даже если вы знаете, что у вас есть непрерывные идентификаторы, я бы порекомендовал использовать ROW_NUMBER
для этого типа запроса в любом случае, чтобы быть в безопасности, потому что пробелы могут испортить его.
CREATE TABLE #tmp (id INT IDENTITY(1,1),stringname NVARCHAR(MAX))
INSERT #tmp (stringname)
VALUES
('stringA')
,('stringA')
,('stringB')
,('stringB')
,('stringA')
,('stringC')
,('stringC')
,('stringC')
,('stringA')
;WITH StringNames
AS(
SELECT
ROW_NUMBER() OVER (ORDER BY ID) AS Row --Accounts for gaps in ID
,stringname
,CAST(NULL AS NVARCHAR(MAX)) AS previous_stringname
FROM #tmp
WHERE id = 1
UNION ALL
SELECT t.Row
,t.stringname
,s.stringname AS previous_stringname
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY ID) AS Row --Accounts for gaps in ID
,stringname
FROM #tmp) AS t
JOIN StringNames AS s ON t.row - 1 = s.row
)
SELECT
DISTINCT
stringname
,previous_stringname
,COUNT(*) AS count
FROM StringNames
GROUP BY
stringname
,previous_stringname
ORDER BY stringname