Problem Statement: I have used the below algorithm for generating all unique combinations for N elements in SQL Server via SQL procedure. I am unable to generate unique combination if N>35, even if I am using BIGINT(2^-63 to (2^63)-1) for storing the value and iterating through the loop. Pseudo-code
N items, indexed 1-N
for i=1 to 2^N-1
for each bit in i
if bit is set, output item[i]
Example for N=4:
N = 4, 2^4 = 16
i = 1: binary = 00000001 -> output I1
i = 2: binary = 00000010 -> output I2
i = 3: binary = 00000011 -> output I1, I2
i = 4: binary = 00000100 -> output I3
i = 5: binary = 00000101 -> output I1, I3
i = 6: binary = 00000110 -> output I2, I3
i = 7: binary = 00000111 -> output I1, I2, I3
i = 8: binary = 00001000 -> output I4
i = 9: binary = 00001001 -> output I1, I4
i = 10: binary = 00001010 -> output I2, I4
i = 11: binary = 00001011 -> output I1, I2, I4
i = 12: binary = 00001100 -> output I3, I4
i = 13: binary = 00001011 -> output I1, I2, I4
i = 14: binary = 00001110 -> output I2, I2, I4
i = 15: binary = 00001111 -> output I1, I2, I3, I4
Below is SQL Code written for the same algorithm.
CREATE PROCEDURE [dbo].[GENERATE_UNIQUE_COMBINATIONS_DIMENSION]
-- Add the parameters for the stored procedure here
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @NO_ITEMS_INPUT INT=(SELECT COUNT(*) FROM TBL_INPUT_DIMENSION)
DECLARE @NO_ITEMS_OUTPUT BIGINT = (SELECT POWER(2,@NO_ITEMS_INPUT)-1)
DECLARE @I BIGINT =1;
DECLARE @BINARY_VALUE VARCHAR(MAX)
DECLARE @BIN_VALUE_REQD VARCHAR(MAX)
--SET @I=@NO_ITEMS_OUTPUT
WHILE (@I<=@NO_ITEMS_OUTPUT)
BEGIN
SET @BINARY_VALUE=[dbo].[CONVERT_INT_BINARY](@I)
SET @BIN_VALUE_REQD = RIGHT(@BINARY_VALUE,@NO_ITEMS_INPUT)
DECLARE @TEMP_STRING VARCHAR(MAX)=''
DECLARE @J BIGINT=1;
WHILE(@J<=@NO_ITEMS_INPUT)
BEGIN
DECLARE @BIT_VALUE CHAR(2)= (SELECT SUBSTRING(@BIN_VALUE_REQD,@J,1))
IF(@BIT_VALUE=1)
BEGIN
DECLARE @INDEX BIGINT= @J
DECLARE @INDEX_VALUE VARCHAR(MAX) = (SELECT INPUT FROM TBL_INPUT_DIMENSION WHERE REF_NO= @J)
SET @TEMP_STRING =@TEMP_STRING+','+@INDEX_VALUE
END
SET @J=@J+1
END
SET @TEMP_STRING = (SELECT SUBSTRING(REPLACE(@TEMP_STRING,' ',''),2,LEN(@TEMP_STRING)))
PRINT @TEMP_STRING
INSERT INTO OUTPUT_DIMENSION VALUES(@I,@TEMP_STRING)
SET @I=@I+1
END
-- Insert statements for procedure here
END