给出一组数据:
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
字母。
我是否在正确的轨道上?有更有效的方法吗?如何防止重叠?
答案 0 :(得分:2)
如果您只是需要将首字母列表分成相当相同的组,那么您应该大致按照您现在的方式进行,但顺序略有不同:
获取表格中的所有首字母。
NTILE结果列表。
对NTILEd结果集进行分组。
WITH letters AS (
SELECT
Letter = LEFT(Name, 1)
FROM #Projects
GROUP BY LEFT(Name, 1)
),
ntiled AS (
SELECT
Letter,
Folder = NTILE(7) OVER (ORDER BY Letter)
FROM letters
)
SELECT
Folder,
FolderCaption = MIN(Letter) + '-' + MAX(Letter)
FROM ntiled
GROUP BY Folder