2010-05-11 169 views
0

可以編寫一個通用函數/過程/ select/somethingElse來交叉連接一個表對自己'n'次? (是的,'n'是給定的參數:)交叉連接'n'次表

你會怎麼做?


有了這個表:

Value 
------- 
    1 
    2 
    3 

交叉連接它的2倍,將返回:

Value | Value 
------------------ 
    1  1 
    1  2 
    1  3 
    2  1 
    2  2 
    2  3 
    3  1 
    3  2 
    3  3 
+1

這不是SQL的預期或適當的用法。 SQL數據庫是以嚴格模式行爲導向的,並且沒有明確的模式。這些操作應該在行上進行,而不是在列上完成。你可以用動態SQL來做到這一點,但它會更好地提出適當的設計。 – Aaronaught 2010-05-11 21:52:46

+0

@AaronNaught謝謝你的解釋Aaron:)+1 – SDReyes 2010-05-11 22:00:00

+0

@AaronNaught我在想:如果交叉連接的結果是以標準化結構返回的,如:(combinationId,value)。你怎麼看? – SDReyes 2010-05-11 22:14:03

回答

5

使用動態SQL,SQL服務器2005+(@table_name和@numCrossJoins存儲過程的參數):

DECLARE @upperLimit INT 
    SET @upperLimit = 1 

DECLARE @SQL NVARCHAR(MAX) 
    SET @SQL = 'SELECT * FROM '+ @table_name +' ' 

BEGIN 

    WHILE (upperLimit <= @numCrossJoins) 
    BEGIN 

    SET @SQL = @SQL + 'CROSS JOIN '+ QUOTENAME(@table_name) +' ' 

    SET @upperLimit = @upperLimit + 1 
    END 

    EXEC sp_executesql @SQL 

END 
+1

這甚至與SQL Server 2000兼容。 – Tomalak 2010-05-11 22:05:00

+0

請將@table_name更改爲QUOTENAME(@table_name),從參數值生成的sp_executing sql只是要求麻煩。 – 2013-07-18 18:09:05

3

您可以生成動態SQL輸出儘可能多根據需要交叉連接:

create table #t (value int) 

insert into #t values (1) 
insert into #t values (2) 
insert into #t values (3) 

declare @n int 
set @n = 4 

declare @sql varchar(max) 
set @sql = 'SELECT * FROM #t t' 
declare @i int 
set @i = 0 
while (@i <= @n) 
begin 
    set @sql = @sql + ' cross join #t t' + CAST(@i as varchar) 
    set @i = @i + 1 
end 

print @sql 
execute(@sql) 

drop table #t 
2

試試這個:

SET @SQL = 'SELECT * FROM ' + replicate('[' + @table_name + '],', @N); 

set @SQL = LEFT(LEN(@SQL) - 1); 

EXEC sp_executesql @SQL;