SQL表,其中包括所有可能分布在三层楼的员工座位表

时间:2019-02-25 19:21:32

标签: sql sql-server

我正在尝试创建一个表,该表显示我的员工所有可能的楼层分配方案。每个楼层都有固定数量的座位,但是每个楼层的确切座位安排无关紧要。

我有30名员工,每个员工的唯一Employee_ID在1-30之间。 我有3层,每层都有固定数量的座位-1层有5个,2层有15个​​,3层有10个。

我尝试了在Employee表(Employee_ID)和Arrangement表(Floor_Number,Seat_Number)之间进行几种不同的交叉联接,但是在将结果组织到可能的方案中时遇到了麻烦。

任何有关如何构建此查询的帮助将不胜感激。

编辑:下面将更详细地描述数据

表-员工

    Employee_ID
    1
    2
    ...
    30

表格-安排

    Floor_Number | Seat_Number
         1       |     1
         1       |     2
         1       |     3
         1       |     4
         1       |     5
         2       |     1
         2       |     2
         ...     |    ...
         2       |     15
         3       |     1
         3       |     2
         ...     |     ...
         3       |     10

所需的输出结构如下表,所有可能的座位分布在3层。我认为将有25种以上的方案-仅作为示例。

    Scenario |  Floor_Number | Seat_Number | Employee_ID
        1    |        1      |      1      |      1
        1    |        1      |      2      |      2
        1    |        1      |      3      |      3
        1    |        1      |      4      |      4
        1    |        1      |      5      |      5
        1    |        2      |      1      |      6
        .............................................
        25   |        1      |      1      |      17
        25   |        1      |      2      |      22
        25   |        1      |      3      |      3

2 个答案:

答案 0 :(得分:1)

没有完整的答案。
只是一个座位数较少的例子。

即使只有9个座位,您也会遇到很多情况。
有了30,那就太疯狂了!

declare @Employees table (id int primary key);
insert into @Employees (id) values 
(1),(2),(3),(4),(5),(6),(7),(8),(9);

IF OBJECT_ID('tempdb..#Scenarios') IS NOT NULL DROP TABLE #Scenarios;
create table #Scenarios (id int primary key identity(1,1), f1e1 int, f1e2 int, f1e3 int, f1e4 int, f2e1 int, f2e2 int, f2e3 int, f3e1 int, f3e2 int);

INSERT INTO #Scenarios (f1e1, f1e2, f1e3, f1e4, f2e1, f2e2, f2e3, f3e1, f3e2)
SELECT DISTINCT 
 e1.id, e2.id, e3.id, e4.id, e5.id, e6.id, e7.id, e8.id, e9.id
FROM @Employees e1
JOIN @Employees e2 ON e2.id > e1.id
JOIN @Employees e3 ON e3.id > e2.id
JOIN @Employees e4 ON e4.id > e3.id
-- floor 2
JOIN @Employees e5 ON e5.id not in (e1.id, e2.id, e3.id, e4.id)
JOIN @Employees e6 ON e6.id not in (e1.id, e2.id, e3.id, e4.id) and e6.id > e5.id
JOIN @Employees e7 ON e7.id not in (e1.id, e2.id, e3.id, e4.id) and e7.id > e6.id
 -- floor 3
JOIN @Employees e8 ON e8.id not in (e1.id, e2.id, e3.id, e4.id, e5.id, e6.id, e7.id)
JOIN @Employees e9 ON e9.id not in (e1.id, e2.id, e3.id, e4.id, e5.id, e6.id, e7.id) and e9.id > e8.id
ORDER BY e1.id, e2.id, e3.id, e4.id, e5.id, e6.id, e7.id, e8.id, e9.id;

select count(*) as Total
from #Scenarios;

select top 3 *
from #Scenarios
order by id desc;

返回:

Total
1260

id      f1e1    f1e2    f1e3    f1e4    f2e1    f2e2    f2e3    f3e1    f3e2
1260    6       7       8       9       3       4       5       1       2
1259    6       7       8       9       2       4       5       1       3
1258    6       7       8       9       2       3       5       1       4

结果表的格式不同。
但是仍然还有UNPIVOT。

答案 1 :(得分:0)

您应该分部分进行。格式不同,但是创建具有5000亿个组合乘以每个组合30行的表是没有意义的。

首先,创建此表,该表在1层的30人中有5人有不同的座位位置。完成这一部分后,您可以通过构造相同类型的脚本,用剩余25人中的10人进行相同的练习额外的NOT IN @ floor_1子句。

如果您确实想要所有行,则可以使用ID值交叉连接到@ floor_2表。

declare @Employees table (id int primary key);
insert into @Employees (id) values 
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29),(30);

declare @floor_1 table (
    id int primary key identity(1,1), 
    emp1 int, 
    emp2 int, 
    emp3 int, 
    emp4 int,
    emp5 INT
    )

INSERT INTO @floor_1
(emp1,emp2,emp3,emp4,emp5)
SELECT a.ID, b.ID, c.ID, d.ID, e.ID
FROM @Employees a
INNER JOIN @Employees b
ON b.ID > a.ID
INNER JOIN @Employees c
ON c.ID > b.ID
INNER JOIN @Employees d
ON d.ID > c.ID
INNER JOIN @Employees e
ON e.ID > d.ID
ORDER BY a.ID, b.ID, c.ID, d.ID, e.ID

SELECT * FROM @floor_1