是否可以通过重复TableB将TableA的每一行连接到较小的TableB的行,但是需要多次?


8

抱歉,标题令人困惑,我不确定在那里写什么。

我有一张有几百条记录的表。我需要将此表的每条记录分配给一个较小的动态用户表,并且用户应交替选择要分配的记录。

例如,如果TableA是

Row_Number()ID
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10

并且TableB是

Row_Number()ID
1 1
2 2
3 3

我需要的最终结果是

用户编号RecordId
1 1
2 2
3 3
1 4
2 5
3 6
1 7
2 8
3 9
1 10

我已经设法使用mod运算符做了一些混乱,但是我很好奇是否可以在没有temp表和变量的情况下运行相同的查询。

使用临时表是因为TableA实际上是一个用户定义函数,它将逗号分隔的字符串转换为表,并且我需要UDF中的对象计数。

-- Converts a comma-delimited string into a table
SELECT Num as [UserId], Row_Number() OVER (ORDER BY (SELECT 1)) as [RowNo]
INTO #tmpTest
FROM dbo.StringToNumSet('2,3,1', ',') 

DECLARE @test int
SELECT @test = Count(*) FROM #tmpTest

SELECT *
FROM #tmpTest as T1
INNER JOIN (
    SELECT Top 10 Id, Row_Number() OVER (ORDER BY SomeDateTime) as [RowNo]
    FROM TableA WITH (NOLOCK)
) as T2 ON T1.RowNo = (T2.RowNo % @test) + 1

同样重要的是,UserId也要交替显示。我无法将记录的前1/3分配给User1,将记录的第二1/3分配给User2,将记录的第三1/3分配给User3。

另外,UserId需要保持最初输入的顺序,这就是为什么我Row_Number() OVER (ORDER BY (SELECT 1))在用户表中有一个

有没有一种方法可以在单个查询中连接这些表,所以我不需要使用临时表和变量?

我正在使用SQL Server 2005

Answers:


12

避免临时表的另一种方法是:

;WITH tmpTest AS
(
    SELECT  Num as [UserId]
            , Row_Number() OVER (ORDER BY (SELECT 1)) as [RowNo]
            , COUNT(*) OVER() AS Quant
    FROM dbo.StringToNumSet('2,3,1', ',') 
)
SELECT *
FROM tmpTest as T1
INNER JOIN 
    (
        SELECT Top 10 Id
            , Row_Number() OVER (ORDER BY SomeDateTime) as [RowNo]
        FROM TableA WITH (NOLOCK)
    ) as T2 ON T1.RowNo = (T2.RowNo % Quant) + 1;

唉唉我不知道我可以使用Count(*)OVER()获得记录计数而不实际分组的记录。这使我可以摆脱临时表和变量,谢谢:)
Rachel

6

是的,您可以在没有任何临时表的情况下执行此操作:

with w as (select usr_id, row_number() over (order by usr_id) as usr_ordinal from usr)
select record_id, ( select usr_id
                    from w
                    where usr_ordinal=1+(record_ordinal%(select count(*) from w))
                  ) as usr_id
from ( select record_id, row_number() over (order by record_id) as record_ordinal 
       from record ) as z;

请参阅此处以获取SQLFiddle演示


尽管这确实摆脱了临时表和变量,但我不喜欢您需要为每个记录运行子查询的事实:)
Rachel 2012年

4
@Rachel只是因为它的声明方式并不意味着它就是执行方式。
亚伦·伯特兰

@AaronBertrand是的,但是不喜欢相信SQL的编译器为我确定一个好的执行计划,这比我必须要做的更多。过去,这对我造成了麻烦:)
Rachel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.