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

时间:2015-01-15 19:07:40

标签: sql sql-server

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

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

SELECT TOP 50 PERCENT * 
FROM MyTable 
ORDER BY MyField ASC

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

SELECT TOP 50 PERCENT * 
FROM MyTable 
ORDER BY MyField DESC

但我无法弄清楚如何选择,比方说,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

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

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

  

当EXISTS没有引入子查询时,只能在选择列表中指定一个表达式。

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

2 个答案:

答案 0 :(得分:6)

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

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

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

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

答案 1 :(得分:0)

当您编写类似column_name'in'或'not in'的条件时,子查询应仅返回一列作为比较结果。 在您的子查询中,您将返回所有列,因此无法进行比较..请尝试以下查询

SELECT * 
FROM MyTable 
WHERE MyField NOT IN (SELECT TOP 50 PERCENT MyField 
                  FROM MyTable 
                  ORDER BY MyField DESC) 
AND MyField NOT IN (SELECT TOP 25 PERCENT MyField 
                  FROM MyTable 
                  ORDER BY MyField ASC) 
ORDER BY MyField ASC