在一个工作坊中,3 人或更多人按照不同的时间表一起工作。例如,3 个 PersonID 分别是 5215、18943 和 21488。
tblTimetable
我有一张这样的桌子:
CREATE TABLE tblTimetable
(
PersonID INT,
TimetableID INT
);
INSERT INTO tblTimetable (PersonID, TimetableID)
VALUES (5215, 57), (18943, 221), (18943, 230), (18943, 238),
(21488, 257), (21488, 270), (5215, 67), (5215, 77),
(5215, 87), (5215, 97);
通过这个选择:
SELECT PersonID, TimetableID
FROM tblTimetable
我得到了以下一组源行:
PersonID TimetableID
5215 57
18943 221
18943 230
18943 238
21488 257
21488 270
5215 67
5215 77
5215 87
5215 97
每对 (PersonID, TimetableID) 都是不可更改的实心块。我想选择所有对 (PersonID, TimetableID) 的组合。
每个 TimetableID 都定义在一个单独的表中tblTimetableDetail
,这里不进行处理,但稍后将会查询它以便在 Microsoft Access 报告上进行绘图。
CREATE TABLE tblTimetableDetail
(
TimetableID INT,
WeekdayID INT,
BeginTime DATETIME,
EndTime DATETIME
);
到目前为止我尝试过这个:
SELECT PersonID, MIN(TimetableID)
FROM tblTimetable
GROUP BY PersonID
UNION ALL
SELECT PersonID, MAX(TimetableID)
FROM tblTimetable
GROUP BY PersonID
我得到了两种 PersonID、TimetableID 对的组合:
PersonID TimetableID
5215 57
18943 221
21488 257
5215 97
18943 238
21488 270
我想获得 PersonID - TimetableID 对组合的详尽列表,所有 PersonID 必须以任意组合形式存在。但顺序无关紧要:
CombiNo PersonID TimetableID
1 5215 57
1 18943 221
1 21488 257
2 5215 57
2 18943 221
2 21488 270
3 5215 57
3 18943 230
3 21488 257
4 5215 57
4 18943 230
4 21488 270
5 5215 57
5 18943 238
5 21488 257
6 5215 57
6 18943 238
6 21488 270
7 5215 67
7 18943 221
7 21488 257
8 5215 67
8 18943 221
8 21488 270
9 5215 67
9 18943 230
9 21488 257
10 5215 67
10 18943 230
10 21488 270
11 5215 67
11 18943 238
11 21488 257
12 5215 67
12 18943 238
12 21488 270
13 5215 77
13 18943 221
13 21488 257
14 5215 77
14 18943 221
14 21488 270
15 5215 77
15 18943 230
15 21488 257
16 5215 77
16 18943 230
16 21488 270
17 5215 77
17 18943 238
17 21488 257
18 5215 77
18 18943 238
18 21488 270
19 5215 87
19 18943 221
19 21488 257
20 5215 87
20 18943 221
20 21488 270
21 5215 87
21 18943 230
21 21488 257
22 5215 87
22 18943 230
22 21488 270
23 5215 87
23 18943 238
23 21488 257
24 5215 87
24 18943 238
24 21488 270
25 5215 97
25 18943 221
25 21488 257
26 5215 97
26 18943 221
26 21488 270
27 5215 97
27 18943 230
27 21488 257
28 5215 97
28 18943 230
28 21488 270
29 5215 97
29 18943 238
29 21488 257
30 5215 97
30 18943 238
30 21488 270
如何用 T-SQL 实现这一点?
使用好的 SQL 字符串,我可以对报告进行 PassThrough 查询作为 .RecordSource,绘制 30 页时间表,每页每个组合。
https://dbfiddle.uk/PLiK04hT
您可以使用 SQLServer 语法将 JSON 数组转换为行。
(以 ORACLE 版本为例:https://dbfiddle.uk/6VGG4Uad)
我们可以将这项任务视为对集合成员进行唯一组合 - 每个组合应该有每个集合的 1 个成员。
有了这些测试数据,我们有 3 组
因此组合数为 5*3*2=30 -
totOver
。我们可以将每行乘以(生成系列)到 (totOver/rQty) 行。
例如
三元组中的最后一个数字是组号。
查看示例
PrepRn
输出.....
小提琴
小提琴
假设您可以从 SQL Server 2022 开始访问
GENERATE_SERIES()
,那么您不需要递归或连接,只需要一点数学运算和使用适当 ID 复制行。就你的情况而言,有 30 种组合 (
5 from person A
*3 from person B
*2 from person c
==30
)这意味着:
每行
person A
需要重复 6 次每行
person B
需要重复 10 次每行
person C
需要重复 15 次每个重复项都需要不同的
combo_id
,例如person A
:这可以通过以下方式实现,
GENERATE_SERIES(original_row_id, 30, 5)
其中30
是组合的总数,5
是当前拥有的行数person
。Using
CROSS APPLY
means that we can generate a different series (generating different number of duplicates, with differingcombination_d
values) for each person and each of their rows.fiddle
尝试从原始表中删除 x 的匹配项,就像在这个 cte 查询中一样。您可以根据此逻辑准备一个存储过程,或者如果可能的话为 cte 查询添加递归性(抱歉,我在这方面不太擅长。)
进行三向交叉连接。由于不平等,某个人不会被选中多次。