Учитывая набор данных, таких как:
id Name
1 Aaa
2 Aab
3 AAc
…
999 Zzz
, я хотел бы создать виртуальные папки, которые разбивают его по начальной букве.Например, я хотел бы передать 7
функции и получить 7 папок, например:
… каждый из которых содержит соответствующее значение (например, T-Z
будет содержать Zzz
).Я понял, что могу использовать NTILE()
, чтобы получить достаточно близко к желаемому результату:
WITH Ntiles(Name, Ntile) AS (
SELECT Name, NTILE(7) OVER(ORDER BY Name) FROM #Projects
)
SELECT MIN(LEFT(N.Name, 1)) + '-' + MAX(LEFT(N.Name, 1))
FROM Ntiles N
GROUP BY Ntile
Чтобы добавить нужные значения, я делаю еще два соединения:
WITH Ntiles(Name, Ntile) AS (
SELECT Name, NTILE(7) OVER(ORDER BY Name) FROM #Projects
) SELECT P.Name, (
SELECT MIN(LEFT(N1.Name, 1)) + '-' + MAX(LEFT(N1.Name, 1)) FROM Ntiles N1
WHERE N1.Ntile = N2.Ntile
GROUP BY N1.Ntile
) FROM #Projects P INNER JOIN Ntiles N2 ON P.Name = N2.Name
… что кажется немного неэффективным.
Но это также неправильно: есть совпадение (например, буква P
появляется в J-P
и P-T
).
Я на правильном пути?Есть ли более эффективный способ?Как предотвратить перекрытие?