我想加入表并获得以下输出
表1
TestId1
----------
one
two
three
four
five
six
seven
eight
表2
TestId2
----------
fiftythree
fiftyfour
fiftytwo
fiftyfive
fiftyone
我希望Table3作为输出,包含table1中的所有行和table2中的第一行,直到没有剩余的行,然后它们应该重复开始。
作为替代答案,它们也可以随机分配。
TestId1 TestId2
---------- ----------
one fiftythree
two fiftyfour
three fiftytwo
four fiftyfive
five fiftyone
six fiftythree
seven fiftyfour
eight fiftytwo
答案 0 :(得分: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中有更多元素。如果你不喜欢这个解决方案,我只是给你很好的基础来编写商店程序。
答案 1 :(得分: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
答案 2 :(得分: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 @rowno=@rowno+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
答案 3 :(得分:1)
我更喜欢随机过程,所以选择 [伪]随机解决方案 ;-)
这也需要在Table2上“引入”一个行号,但是与Table1的连接是由Table1的某些列上的某些哈希[以Tableol的行数为模]驱动的(不一定是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
答案 4 :(得分:0)
您可能想尝试在ROWNUM上加入。
答案 5 :(得分:-1)
我认为一个选择的所有解决方案都非常难看。我认为最好使用带有两个游标的存储过程(在每个表上)