Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Randomization Revisited (with Constriants)

Author  Topic 

budgie
Starting Member

18 Posts

Posted - 2004-05-11 : 12:09:13
I currently have a stored procedure that handles some basic randomization on a set of data similar to the one below:

CREATE PROCEDURE [usp_random]
@int_records INT,
@int_parent INT
AS
SET NOCOUNT ON
DECLARE @int_rc INT
DECLARE @int_idx_1 INT
DECLARE @int_idx_1 INT
DECLARE @int_cross INT
DECLARE @str_exec NVARCHAR(200)

CREATE TABLE #result (
int_id INT IDENTITY(1, 1) NOT NULL,
int_id_data INT,
int_idx INT
)

INSERT INTO #result SELECT (int_id) FROM tbl_some_data WHERE int_parent = @int_parent

SET @int_rc = @@ROWCOUNT

IF @int_rc > 0
BEGIN
IF @int_rc < @int_records SET @int_records = @int_rc

UPDATE #result SET int_idx = int_id

SET @int_idx_1 = 0
WHILE @int_idx_1 < @int_records
BEGIN
SET @int_idx_1 = @int_idx_1 + 1
SET @int_idx_2 = FLOOR(RAND() * @int_rc) + 1)
SET @int_cross = (SELECT int_idx FROM #result WHERE int_id = @int_idx_1)

UPDATE #result
SET int_idx = (SELECT int_idx FROM #result WHERE int_id = @int_idx_1)
WHERE int_idx = @int_idx_1

UPDATE #result
SET int_idx = @int_cross
WHERE int_idx = @int_idx_2
END

SET @str_exec = 'SELECT TOP ' + @int_records
+ ' d.*, r.int_idx FROM tbl_some_data AS d '
+ 'JOIN #result AS b ON d.int_id = r.int_id_data ORDER BY r.int_idx'

SET NOCOUNT OFF

EXECUTE(@str_exec)
END
ELSE
SET NOCOUNT OFF

SELECT NULL
END IF


I was just about to change it for one using ORDER BY NEWID() instead when some constriants were given to me. Basically I have to add 2 constriants to the current, however the are both basically the same just different data fields in the data table. So I will just deal with one here. There is a int field that groups records in the table together, it is either zero meaning that the record isn't grouped or an id for the group that it is in.

Now I need to make this SP produce a result set that still returns X records but if there are enough records only return one from each non-zero group id. e.g. if I had

ID gid
----------- -----------
21 0
24 0
25 0
76 0
704 0
896 0
3493 0
4215 3
4679 0
4768 0
40300 0
41177 3
41233 0

and wanted to get 5 ID from it I would only ever see either of ID's 4215 and 41177 or neither but definitely not both in my returned recordset. Whereever possible the procedure must return X records even if that means padding it out with extra records from groups.

Currently my idea is to get the all the records for randomization, randonmize them. Then if necessary remove all bar the top listed record in the group by creating a second temp table and only allowing 1 record from each group to be in there and padding it out if necessary. Finally re-randomizing it.

This seems a long way around and I was wondering if anyone might have some further suggestions to it.

Graham
   

- Advertisement -