2009-10-01 81 views
0

我想加入到表,並得到下面的輸出連接表(無條款)

表1

TestId1 
---------- 
one 
two 
three 
four 
five 
six 
seven 
eight 

表2

TestId2 
---------- 
fiftythree 
fiftyfour 
fiftytwo 
fiftyfive 
fiftyone 

我想表3爲我的輸出來自table1的所有行和來自table2的第一行,直到沒有剩下的行,然後它們應該開始重複。

作爲替代答案,它們也可以隨機分配。

TestId1  TestId2 
----------  ---------- 
one   fiftythree 
two   fiftyfour 
three   fiftytwo 
four   fiftyfive 
five   fiftyone 
six   fiftythree 
seven   fiftyfour 
eight   fiftytwo 
+0

您必須完成它只有一個選擇或存儲過程被允許? – 2009-10-01 16:26:24

回答

5

試試這個:

SELECT t1.name, t2.name FROM 
(
    SELECT (ROW_NUMBER() OVER(ORDER BY name)-1)%(SELECT COUNT(*) FROM test2) AS j,* 
    FROM test1 
) t1 
INNER JOIN 
(
    SELECT ROW_NUMBER() OVER(ORDER BY name)-1 AS j,* 
    FROM test2 
) t2 ON t1.j = t2.j 
ORDER BY t1.name 

在細節:

SELECT (ROW_NUMBER() OVER(ORDER BY name)-1) AS j,* 
FROM test1 

返回:

0 | one 
1 | two 
2 | three 
3 | four 
4 | five 
5 | six 
6 | seven 
7 | eight 

此:

SELECT ROW_NUMBER() OVER(ORDER BY name)-1 AS j,* 
FROM test2 

返回:

0 | fiftythree 
1 | fiftyfour 
2 | fiftytwo 
3 | fiftyfive 
4 | fiftyone 

所有你需要做的是分裂 - 由元素的數量(%我不知道這個英文名)的最長表的第一列短:

SELECT (ROW_NUMBER() OVER(ORDER BY name)-1)%(SELECT COUNT(*) FROM test2) AS j,* 
FROM test1 

返回:

0 | one 
1 | two 
2 | three 
3 | four 
4 | five 
0 | six 
1 | seven 
2 | eight 

所有你現在要做的是加入微博第一列的第一個表格。

該解決方案是通過僅使用一個查詢來完成的,但它假設在table1中有更多的元素,然後在table2中。如果你不喜歡這個解決方案,我只是給你編寫存儲過程的良好基礎。

+0

「(% - 我不知道這個的英文名稱)」 - modulo(或mod) – 2009-10-01 17:03:11

+0

當然,你是對的! O我昨天在工作時間太多了:p – 2009-10-01 17:13:32

1

您的替代解決方案是唯一一個

SELECT 
    TestID1, 
    TestID2 
FROM 
    (SELECT COUNT(*) AS Count1 FROM Table1) C1 --one row 
    CROSS JOIN 
    (SELECT COUNT(*) AS Count2 FROM Table2) C2 --one row 
    CROSS JOIN 
    (
    SELECT 
     ROW_NUMBER() OVER (ORDER BY TestID1) AS Rank1, 
     TestID1, 
    FROM 
     Table1 
    ) t1 
    JOIN 
    (
    SELECT 
     ROW_NUMBER() OVER (ORDER BY TestID1) AS Rank2, 
     TestID2, 
    FROM 
     Table2 
    ) t2 ON 
     t1.Rank1 % CASE WHEN C1.Count1 > C2.Count2 THEN C2.Count2 ELSE 2000000000 END 
     = 
     t2.Rank2 % CASE WHEN C2.Count2 > C1.Count1 THEN C1.Count1 ELSE 2000000000 END 
ORDER BY 
    t1.Rank1, t2.Rank2 
-1

我想通過一個選擇所有的解決方案是十分可怕的。我想更好地利用存儲過程與兩個光標(在每個表)

+0

切勿使用遊標,因爲您不喜歡基於集合的解決方案的外觀或認爲它們很複雜。瞭解如何改爲基於集合的解決方案。當存在基於集合的解決方案時,使用遊標的做法很差。 – HLGEM 2009-10-01 17:18:27

1

這這裏工作並且只有一個光標:

if exists(select object_id('tempdb..#TestId1')) 
drop table #TestId1 

if exists(select object_id('tempdb..#TestId2')) 
drop table #TestId2 

if exists(select object_id('tempdb..#result')) 
drop table #result 

create table #TestId1(col_1 varchar(100)) 

create table #TestId2(col_2 varchar(100)) 

create table #result (col_1 varchar(100), col_2 varchar(100)) 

set rowcount 0 

insert into #TestId1(col_1) 
select col='one' 
union all select col='two' 
union all select col='three' 
union all select col='four' 
union all select col='five' 
union all select col='six' 
union all select col='seven' 
union all select col='eigh' 

insert into #TestId2(col_2) 
select col='fiftythree' 
union all select col='fiftyfour' 
union all select col='fiftytwo' 
union all select col='fiftyfive' 
union all select col='fiftyone' 

DECLARE @sectblcnt int 
select @sectblcnt=count(*) from #TestId2 

DECLARE @sectableNo int 

DECLARE @rowno int 

declare @col_1 varchar(100), @col_2 varchar(100) 

set @rowno=0 

DECLARE curs CURSOR FOR SELECT col_1 FROM #TestId1 

OPEN curs 

FETCH NEXT FROM curs INTO @col_1 

WHILE @@FETCH_STATUS = 0 
BEGIN 
set @[email protected]+1; 

set @sectableNo = @rowno % @sectblcnt 
set rowcount @sectableNo 

select @col_2=col_2 from #TestId2 

insert into #result(col_1, col_2) 
    values(@col_1, @col_2) 

FETCH NEXT FROM curs 
INTO @col_1 
END 

CLOSE curs 

DEALLOCATE curs 

set rowcount 0 

select * from #result 
1

我喜歡隨機過程,所以拍得[僞]隨機解決方案 ;-)

這也需要在表2上「誘導」一個行號,但與Table1的連接是由表1的一些列上的一些哈希[以模塊化表2的行數爲模]驅動的不必是TestId1)。

SELECT T1.TestId1, T2.TestId2 
FROM Table1 T1 
JOIN (
    SELECT (ROW_NUMBER() OVER(ORDER BY TestId2) - 1) AS RowNum, TestId2 
    FROM Table2 
) T2 ON ABS(HashBytes ('MD5', T1.TestId1) % (SELECT COUNT(*) FROM Table2)) 
     = T2.RowNum 
ORDER BY t1.TestId1