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

kon*_*_pe 4 sql sql-server select sql-server-2008

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

我已经有了这样做的方法:我计算感兴趣的时间段中的行,使用简单的"where"子句来指定sensor-id,将其保存为SQL中的变量,然后将count()除以1000我已经在MS Access中尝试过了,它运行得很好:

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

SELECT (Int([RowNumber]/@divider)), First(Value)
FROM myTable
GROUP BY (Int([RowNumber]/@divider));
Run Code Online (Sandbox Code Playgroud)

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


更新:解决方案!非常感谢/sf/users/3681891/ !!!

这是我最终如何做到的:

我声明了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'
)
Run Code Online (Sandbox Code Playgroud)

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

现在我有舍入值,我想成为我的步长(取每个第x个值 - >这是我们的"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
Run Code Online (Sandbox Code Playgroud)

像魅力一样 - 再次感谢/sf/users/3681891/,请参阅下面的评论原始帖子!

Lie*_*ers 6

实质上,您需要做的就是选择第x个值,保留所有行,其中rownumber的模数除以x为0.

WHERE rn % @x_thValues = 0
Run Code Online (Sandbox Code Playgroud)

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

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

结合变量到你需要的x值,可以使用类似于这个测试脚本的东西

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                    
Run Code Online (Sandbox Code Playgroud)