1

给定一组数据,例如:

id    Name
   1  Aaa
   2  Aab
   3  AAc
…
 999  Zzz

,我想创建按首字母对其进行分区的虚拟文件夹。例如,我想传递7给一个函数并获取 7 个文件夹,例如:

  • 交流电
  • 东风
  • 生长激素
  • 我是
  • NQ
  • RS
  • 太极

…其中每个都包含各自的值(例如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)。

我在正确的轨道上吗?有没有更有效的方法?如何防止重叠?

4

1 回答 1

2

如果您只是需要将初始字母列表分成相当相等的组,那么您可能应该大致按照您到目前为止所做的方式执行此操作,但顺序略有不同:

  1. 获取表中的所有首字母。

  2. NTILE 结果列表。

  3. 对 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
于 2011-05-07T19:31:03.340 回答