如何从数据库表中选择4个大小相同的结果集

kiv*_*all 3 sql sql-server

我有一个SQL Server数据库表,有很多行.我正在使用一个使用该表作为数据源的程序.程序本身不支持多线程,所以我必须运行程序的多个实例,并且我需要告诉每个实例要处理整个基础数据的哪个部分.

我一直在使用这个语句将我的基础数据(表中的数据)分割成两个大小相同的结果集:

SELECT TOP 50 PERCENT * 
FROM MyTable 
ORDER BY MyField ASC
Run Code Online (Sandbox Code Playgroud)

因此,这将选择前50%的数据.然后我使用以下语句返回另一半:

SELECT TOP 50 PERCENT * 
FROM MyTable 
ORDER BY MyField DESC
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何选择,比方说,25%的块.我试过这样的

SELECT * 
FROM MyTable 
WHERE MyField NOT IN (SELECT TOP 50 PERCENT * 
                      FROM MyTable 
                      ORDER BY MyField DESC) 
  AND MyField NOT IN (SELECT TOP 25 PERCENT * 
                      FROM MyTable 
                      ORDER BY MyField ASC) 
ORDER BY MyField ASC
Run Code Online (Sandbox Code Playgroud)

所以它会返回其他所有内容但不是前25%或后50%.换句话说,它会返回25%行和50%之间的数据.你明白我的意思.

我用我的本地机器(在连接到我的SQL数据库的Visual Studio中)尝试了这个并且它运行良好但是当我在测试环境中实现它时我收到以下错误

当未使用EXISTS引入子查询时,只能在选择列表中指定一个表达式.

我真的不知道在这种情况下这意味着什么.这些SELECT TOP 50 PERCENT陈述也适用于测试环境.

mar*_*c_s 6

您应该查看NTILE窗口函数 - 它将一组行分成块(其中任意数量 - 您决定)并允许您轻松选择所需的行:

WITH ChunkedData AS
(
    SELECT 
        Chunk = NTILE(4) OVER (ORDER BY MyField ASC),
        * 
    FROM MyTable 
)
SELECT *
FROM ChunkedData
WHERE Chunk = 1
Run Code Online (Sandbox Code Playgroud)

使用NTILE(4)窗口功能,您基本上可以获得标有1,2,3或4 - 4个几乎相等的数据块的所有行.选择你需要的那个 - 就像一个魅力!

当然,如果你需要,你可以使用其他数量的块 - NTILE(10)给你10个同样大小的块 - 你的选择.