SQL Server:如何选择固定数量的行(选择每个第x个值)

时间:2012-03-19 20:11:36

标签: sql sql-server sql-server-2008 select

简短描述:我有一个表格,其中包含在特定时间段内更新的数据。现在的问题是,根据发送数据的传感器的性质,在这段时间内可能有50个数据集或50.000个数据集。由于我想要显示这些数据(使用ASP.NET / c#),对于第一次预览,我想从表中只选择1000个值。

我已经有了这样做的方法:我计算感兴趣的时间段中的行,用一个简单的“where”子句来指定sensor-id,将其保存为SQL中的变量,然后除以计数( )我已经在MS Access中尝试了它,它可以正常工作:

set @divider = select count(*) from table where [...]

SELECT (Int([RowNumber]/@divider)), First(Value)
FROM myTable
GROUP BY (Int([RowNumber]/@divider));

Access中的技巧是,我只有一个数据字段(“RowNumber”),这是我的PK / ID,从0开始。我尝试使用ROW_NUMBER()方法在SQL Server中实现这一点,该方法或多或少有效。我有方法的正确语法,但我不能使用GROUP BY语句

  

窗口函数只能出现在SELECT或ORDER BY中   条款。

意味着ROW_NUMBER()不能出现在GROUP BY声明中。

现在我有点卡住了。我试图将ROW_NUMBER值保存到char或单独的列中,稍后GROUP BY将其保存,但我无法完成。不知怎的,我开​​始想,我的策略可能有它的弱点......? :/

再次澄清:我不需要从我的表中SELECT TOP 1000,因为这只是意味着我选择了前1000个值(取决于排序)。我需要SELECT每个x值,而我可以计算x(我甚至可以将它舍入到INT,如果这有助于完成它)。我希望我能够描述这个问题是可以理解的......

这是我在StackOverflow上的第一篇文章,我希望我没有忘记任何重要或重要的内容,如果您需要任何进一步的信息(表结构,我的查询到目前为止,......)请不要犹豫。任何帮助或提示都非常感谢 - 提前感谢! :)


更新:解决方案!非常感谢https://stackoverflow.com/users/52598/lieven !!!

以下是我最终的表现:

我声明了2个变量 - 我计算我的行并将其设置为第一个var。然后我在刚分配的变量上使用ROUND(),并将其除以1000(因为最后我想要大约1000个值!)。我将此操作拆分为2个变量,因为如果我使用COUNT函数的值作为我的ROUND操作的基础,那么就会出现一些错误。

declare @myvar decimal(10,2) 
declare @myvar2 decimal(10,2)

set @myvar = (select COUNT(*)
from value_table
where channelid=135 and myDate >= '2011-01-14 22:00:00.000' and myDate <= '2011-02-14 22:00:00.000'
)

设置@ myvar2 = ROUND(@ myvar / 1000,0)

现在我有了舍入值,我希望它是我的步长(取每个x值 - &gt;这是我们的“x”;)存储在@ myvar2中。接下来,我将选择所需时间跨度和通道的数据,并将ROW_NUMBER()添加为列“rn”,最后将WHERE子句添加到外部SELECT,其中我将ROW_NUMBER除以@myvar2 - 当模数为0,该行将被选中。

select * from
(
select (ROW_NUMBER() over (order by id desc)) as rn, myValue, myDate
from value_table
where channel_id=135 and myDate >= '2011-01-14 22:00:00.000' and myDate<= '2011-02-14 22:00:00.000'
) d
WHERE rn % @myvar2 = 0

像魅力一样 - 再一次感谢https://stackoverflow.com/users/52598/lieven,请看下面的评论原始发布!

2 个答案:

答案 0 :(得分:6)

本质上,你需要做的就是选择第x个值,保留rownumber除以x的模数为0的所有行。

WHERE rn % @x_thValues = 0

现在为了能够使用ROW_NUMBER的结果,您需要将整个语句包装在子选择中

SELECT  *
FROM    (
            SELECT  *
                    , rn = ROW_NUMBER() OVER (ORDER BY Value)
            FROM    DummyData
        ) d
WHERE   rn % @x_thValues = 0                    

将变量与您需要的x值相结合,您可以使用类似于此testcript

的内容
DECLARE @x_thValues INTEGER = 2

;WITH DummyData AS (SELECT * FROM (VALUES (1), (2), (3), (4)) v (Value))
SELECT  *
FROM    (
            SELECT  *
                    , rn = ROW_NUMBER() OVER (ORDER BY Value)
            FROM    DummyData
        ) d
WHERE   rn % @x_thValues = 0                    

答案 1 :(得分:0)

还有另外一个选择:

Select Top 1000 * 
From dbo.SomeTable 
Where ....
Order By NewID()

但老实说 - 就像之前的答案一样。 问题可能在于绩效......

相关问题