问题
I'm using SQL Server 2012 and I'm trying to do something like this:
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
*/
So in other words, I want to select random rows from a table that have a specified from and to date and stop when the sum of miles is at or over the number: 3250
回答1:
Since you're using SQL Server 2012, here is a much easier approach that doesn't require looping.
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 - hit "Run SQL" multiple times to see random results.
回答2:
You can do SELECT TOP x ... ORDER BY newid() to get a sum of random rows. The problem lies in determining 'x'. You can't even be sure that the largest value of 'x' (number of rows that match the query) will have a total large enough to meet your requirements without testing that first:
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
Just a note about this - the algorithm starts and 1 and increments up until a suitable match is found. A more efficient approach (for larger sets of data) might include a binary type search that caches the lowest suitable result and returns when the deepest node (or an exact match) is found.
回答3:
I can't think of a way without a TSQL While... loop. This in combination with the TSQL paging with ROW_NUMBER() should get you there.
http://www.mssqltips.com/sqlservertip/1175/page-through-sql-server-results-with-the-rownumber-function/
In the ROW_NUMBER query, sum the Miles into another MileSum column, then in the while loop select the set all the rows that correspond with the ROW_NUMBER query while accumulating these MileSum values into a variable. Terminate when the variable exceeds 3250.
回答4:
Try
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
and then you can add a TOP 5 or whatever you want. You get those in random order for sure.
回答5:
Just a sample code for you to understand the concept.
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
The reason for this approach is that paging would not return wide spread result unless and until you have thousands of records because in it the data is grouped into pages and with less records, the same page is hit multiple number of times giving the same result.
Also, there might be cases when a blank page is hit giving 0 as the result.(i don't know why sometimes a blank page is hit.)
来源:https://stackoverflow.com/questions/15278143/select-random-rows-and-stop-when-a-specific-sum-total-is-reached