我正在使用SQL Server 2012而我正在尝试这样做:
SELECT SUM(MILES) from tblName WHERE
mDate > = '03/01/2012' and
mDate <= '03/31/2012'
-- and...
/*
now I want to add here do until the SUM of Miles
is equal to or greater then '3250' and get the
results rows randomly
*/
换句话说,我想从表格中选择具有指定日期和日期的随机行,并在英里总和达到或超过该数字时停止:3250
答案 0 :(得分:3)
由于您使用的是SQL Server 2012,因此这是一种更简单的方法,不需要循环。
DECLARE @tbl TABLE(mDate DATE, Miles INT)
INSERT @tbl VALUES
('20120201', 520), ('20120312', 620),
('20120313', 720), ('20120314', 560),
('20120315', 380), ('20120316', 990),
('20120317', 1020), ('20120412', 520);
;WITH x AS
(
SELECT
mDate,
Miles,
s = SUM(Miles) OVER
(
ORDER BY NEWID() ROWS UNBOUNDED PRECEDING
)
FROM @tbl
WHERE mDate >= '20120301'
AND mDate < '20120401'
)
SELECT
mDate,
Miles,
s
FROM x
WHERE s <= 3250
ORDER BY s;
SQLfiddle demo - 多次点击“运行SQL”以查看随机结果。
答案 1 :(得分:2)
您可以SELECT TOP x ... ORDER BY newid()
获取随机行的总和。问题在于确定'x'。您甚至不能确定'x'的最大值(与查询匹配的行数)总数大到足以满足您的要求而不先测试:
DECLARE @stopAt int
DECLARE @x int
DECLARE @result int
SET @stopAt = 3250
SET @x = 1
SELECT @result = SUM(MILES) from tblName
WHERE
mDate >= '03/01/2012' and
mDate <= '03/31/2012'
IF (@result < @stopAt)
SELECT NULL -- this can't be done
ELSE
BEGIN
WHILE (1=1)
BEGIN
SELECT TOP (@x) @result = SUM(MILES) FROM tblName
WHERE
mDate >= '03/01/2012' and
mDate <= '03/31/2012'
ORDER BY newid()
IF @result >= @stopAt
BREAK
SET @x = @x + 1
END
SELECT @result
END
关于这一点的注释 - 算法启动并且1递增直到找到合适的匹配。更有效的方法(对于更大的数据集)可能包括二进制类型搜索,它缓存最低的合适结果,并在找到最深节点(或完全匹配)时返回。
答案 2 :(得分:0)
只是一个示例代码,供您理解这个概念。
create table temp(intt int)
insert into temp values(1)
insert into temp values(2)
insert into temp values(3)
insert into temp values(4)
insert into temp values(5)
insert into temp values(6)
insert into temp values(7)
insert into temp values(8)
insert into temp values(9)
insert into temp values(10)
insert into temp values(11)
insert into temp values(12)
insert into temp values(13)
insert into temp values(14)
insert into temp values(15)
insert into temp values(16)
insert into temp values(17)
insert into temp values(18)
insert into temp values(19)
insert into temp values(20)
insert into temp values(21)
declare @sum int = 0;
declare @prevInt int = 0;
while(@sum<50)
begin
set @prevInt = (select top(1) intt from temp order by newid());
set @sum = @sum + @prevInt;
end
set @sum = @sum-@prevInt;
select @sum
drop table temp
这种方法的原因是分页不会返回广泛传播的结果,除非并且直到你有数千条记录,因为在其中数据被分组到页面并且记录较少,同一页面被多次命中给出同样的结果。
此外,可能会出现一个空白页面被命中为0的情况。(我不知道为什么有时会出现空白页面。)
答案 3 :(得分:0)
我想不出没有TSQL While ...循环的方法。这与使用ROW_NUMBER()的TSQL分页相结合可以帮助您实现目标。
在ROW_NUMBER查询中,将Miles与另一个MileSum列相加,然后在while循环中选择与ROW_NUMBER查询对应的所有行,同时将这些MileSum值累积到变量中。当变量超过3250时终止。
答案 4 :(得分:0)
尝试
SELECT MILES
, RANK() OVER (ORDER BY NEWID()) yourRank
FROM @tblName
WHERE miles>3250
AND mDate >= '03/01/2012'
AND mDate <= '03/31/2012'
ORDER BY yourRank
然后你可以添加TOP 5或任何你想要的。 你肯定会以随机顺序得到那些。