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 INTAS 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 hadID gid ----------- ----------- 21 024 025 076 0704 0896 03493 04215 34679 04768 040300 041177 341233 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