我想寻求有关查询的帮助,该查询可以识别非重叠记录上的组。这是一个示例场景(诚然是人为设计的)。假设我有一些员工被分配到不同的项目上工作。虽然一名员工可以被分配到多个项目,但他/她在任何给定时间只能从事一个项目(难道你不希望我们都拥有这种奢侈吗:)。我需要找出可以安排并行处理哪些项目,因为它们不共享任何员工。下面是一些设置示例表和数据的代码。
--1. Create #Projects table
IF OBJECT_ID('tempdb..#Projects') IS NOT NULL
DROP TABLE #Projects
CREATE TABLE #Projects (
ProjectId INT,
ProjectName VARCHAR(16)
)
INSERT INTO #Projects ( ProjectId, ProjectName )
VALUES ( 1, 'Project 1'), ( 2, 'Project 2'), ( 3, 'Project 3'), ( 4, 'Project 4'), ( 5, 'Project 5'),
( 6, 'Project 6'), ( 7, 'Project 7')
--2. Create #Employees table
IF OBJECT_ID('tempdb..#Employees') IS NOT NULL
DROP TABLE #Employees
CREATE TABLE #Employees (
EmployeeId INT,
EmployeeName VARCHAR(16)
)
INSERT INTO #Employees (EmployeeId, EmployeeName)
VALUES (101, 'Employee 101'), (102, 'Employee 102'), (103, 'Employee 103'), (104, 'Employee 104'),
(105, 'Employee 105'), (106, 'Employee 106'), (107, 'Employee 107')
--3. Create #Employee_Projects table
IF OBJECT_ID('tempdb..#Employee_Projects') IS NOT NULL
DROP TABLE #Employee_Projects
CREATE TABLE #Employee_Projects (
ProjectId INT,
EmployeeId INT
)
INSERT INTO #Employee_Projects (ProjectId, EmployeeId)
VALUES (1, 101), (1, 105), (1, 107), (2, 102), (2, 103), (2, 107), (3, 104), (3, 105), (3, 106), (4, 100), (4, 101), (4, 102), (5, 103), (5, 104), (6, 105), (6, 106), (7, 106), (7, 107), (8, 102), (8, 104), (8, 106)
这是查询,它将向您显示我们创建的员工和项目:
SELECT p.ProjectId, p.ProjectName, e.EmployeeId, e.EmployeeName
FROM #Projects p
JOIN #Employee_Projects ep ON ep.ProjectId = p.ProjectId
JOIN #Employees e ON e.EmployeeId = ep.EmployeeId
ORDER BY ep.ProjectId, e.EmployeeId
我们的数据如下所示:
ProjectId ProjectName EmployeeId EmployeeName
----------- ---------------- ----------- ----------------
1 Project 1 101 Employee 101
1 Project 1 105 Employee 105
1 Project 1 107 Employee 107
2 Project 2 102 Employee 102
2 Project 2 103 Employee 103
2 Project 2 107 Employee 107
3 Project 3 104 Employee 104
3 Project 3 105 Employee 105
3 Project 3 106 Employee 106
4 Project 4 101 Employee 101
4 Project 4 102 Employee 102
5 Project 5 103 Employee 103
5 Project 5 104 Employee 104
6 Project 6 105 Employee 105
6 Project 6 106 Employee 106
7 Project 7 106 Employee 106
7 Project 7 107 Employee 107
8 Project 8 102 Employee 102
8 Project 8 104 Employee 104
8 Project 8 106 Employee 106
从视觉上我们可以看出,例如,我们可以安排项目 1、2、3 同时运行,因为它们不共享任何员工。我们称这组项目为“第 1 组”。之后我们可以安排项目 4、5、6。我们称之为“第 2 组”。最后,在我们的示例中,我们还有项目 7,这将是我们的“第 3 组”。我的问题是,如何编写 T-SQL 查询来执行此类项目分组?
谢谢!
这是一种装箱问题,因此您很可能需要从可用的近似解决方案中进行选择,而不是尝试进行详尽的搜索。
一个非常直接的想法是将项目打包成组,每次选择员工人数最多的项目。一旦当前项目不再适合当前组,我们就开始一个新组。
这相对容易迭代表达,尽管它可能表现不佳,具体取决于真实数据集的特征。在单个 T-SQL 语句中表达相同的逻辑可能非常具有挑战性。不管怎样,作为一个例子,这里有一个使用上面概述的简单贪心算法的迭代 T-SQL 解决方案:
此代码是不确定的,因为遇到的任何联系(按每个项目的员工人数降序排序时)都会使用
NEWID
. 然而,典型的输出是:愿这对你有帮助。