我有3张桌子:
Users
-----
UserID (varchar)
Active (bit)
Refunds_Upload
--------------
BorrowerNumber (varchar)
Refunds
-------
BorrowerNumber
UserID
我首先选择Active = 1的所有UserID值。
我需要将Refunds_Upload中的记录插入退款,但我需要为每个活动用户ID 插入相同(或尽可能接近)的记录数。
例如,如果Refunds_Upload有20条记录而且Users表有5个人,其中Active = 1,那么我需要将每个UserID的4条记录插入表退款。
最终结果将是:
BorrowerNumber UserID
105 Fred
110 Fred
111 Fred
115 Fred
120 Billy
122 Billy
123 Billy
125 Billy
130 Lucius
131 Lucius
133 Lucius
135 Lucius
138 Lucy
139 Lucy
140 Lucy
141 Lucy
142 Grady
143 Grady
144 Grady
145 Grady
当然,它不会总是达到每个用户的偶数记录,所以我也需要考虑到这一点。
答案 0 :(得分:2)
首先运行它并检查它返回类似你要插入的内容,然后取消注释插入并实际执行它..
--INSERT INTO Refunds
SELECT
numbered_u.UserID,
numbered_ru.BorrowerNumber
FROM
(SELECT u.*, ROW_NUMBER() OVER(ORDER BY UserID) - 1 as rown, SUM(CAST(Active as INT)) OVER() as count_users FROM Users u WHERE active=1) numbered_u
INNER JOIN
(SELECT ru.*, ROW_NUMBER() OVER(ORDER BY BorrowerNumber) - 1 as rown, COUNT(*) OVER() as count_ru FROM Refund_Uploads ru) numbered_ru
ON
ROUND(CAST(numbered_ru.rown AS FLOAT) / (count_ru / count_users)) = numbered_u.rown
逻辑:
我们为用户中的每个有趣(active = 1)行编号,我们也将它们全部计算在内。这应该返回给我们所有5个用户,编号为0到4,并且每行的ctr为5。
然后我们将它们加入到类似编号的Refund_Uploads列表中(比如20)。类似地,由于后来变得明显的数学原因,这些行将被编号为0到19。我们也计算所有这些行
然后我们将这两个数据集连接在一起,但条件是一系列值而不是精确值。逻辑是“refund_upload行号,除以_count_of_rows_there_should_be_per_user”(即0..19 /(20/5))= user_row_number。希望因此退回第0行到第3行,与用户0相关联,退回第4行至第7行与用户1相关联等等。
没有完整数据调试有点困难 - 我觉得可能需要在这里和那里进行一些+1 / -1调整。
我最初使用FLOOR但是切换到使用ROUND,因为我认为这可能适用于分配Refund / User中没有整数个分区的数字集合,例如你的240/13例子..希望有些用户会有18行,有些用户可能有19行