我正在研究三个SQL表,并尝试让所有参与所有三个计划的员工如下:
表:员工
╔════════════╦═══════════╦═══════════╦═══════════╦═══════════╦════════╗
║ EmployeeID ║ FirstName ║ LastName ║ Birthdate ║ HomeState ║ Gender ║
╠════════════╬═══════════╬═══════════╬═══════════╬═══════════╬════════╣
║ 1 ║ John ║ Doe ║ 1/1/1978 ║ FL ║ M ║
║ 2 ║ Jane ║ Eyre ║ 4/7/1985 ║ AL ║ F ║
║ 3 ║ Alexander ║ Hamilton ║ 6/4/1960 ║ NY ║ M ║
║ 4 ║ Chris ║ Smith ║ 12/5/1990 ║ CA ║ M ║
║ 5 ║ Emily ║ Dickinson ║ 3/5/1945 ║ VT ║ F ║
╚════════════╩═══════════╩═══════════╩═══════════╩═══════════╩════════╝
表:计划:
╔════════╦══════════╦════════════════╗
║ PlanID ║ PlanType ║ PlanName ║
╠════════╬══════════╬════════════════╣
║ 1 ║ Medical ║ Medical Plan 1 ║
║ 2 ║ Dental ║ Dental Plan 1 ║
║ 3 ║ Vision ║ Vision Plan 1 ║
║ 4 ║ Medical ║ Medical Plan 2 ║
╚════════╩══════════╩════════════════╝
表: PlanEnrollment
╔══════════════╦════════════╦════════╦═════════════════════╦══════════════════╗
║ EnrollmentID ║ EmployeeID ║ PlanID ║ EnrollmentStartDate ║ ErollmentEndDate ║
╠══════════════╬════════════╬════════╬═════════════════════╬══════════════════╣
║ 1 ║ 1 ║ 1 ║ 1/1/2015 ║ 3/1/2015 ║
║ 2 ║ 1 ║ 2 ║ 1/1/2014 ║ NULL ║
║ 3 ║ 2 ║ 1 ║ 6/1/2013 ║ 5/1/2015 ║
║ 4 ║ 3 ║ 4 ║ 2/1/2013 ║ NULL ║
║ 5 ║ 4 ║ 2 ║ 5/3/2015 ║ 7/1/2015 ║
║ 6 ║ 1 ║ 4 ║ 3/2/2015 ║ NULL ║
╚══════════════╩════════════╩════════╩═════════════════════╩══════════════════╝
从上表中我试图检索目前参加所有三项医疗,牙科和视力计划的所有员工的名字和姓氏。
怎么做?
答案 0 :(得分:0)
这应该可以解决问题。我仍然不是SQL专家。我可能会遗漏一些内容。
SELECT * FROM `PlanEnrollment`,`Employee`
WHERE COUNT(`PlanEnrollment`.`EmployeeID`) = 3
AND `PlanEnrollment`.`PlanID` != 4
GROUP BY `PlanEnrollment`.`EmployeeID`
JOIN `Employee` ON `PlanEnrollment`.`EmployeeID` = `Employee`.`EmployeeID`
答案 1 :(得分:0)
这应该
SELECT e.firstname,
e.lastname
FROM Employee e
WHERE NOT EXISTS (SELECT PlanID
FROM Plan
WHERE PlanType IN ('Medical', 'Dental', 'Vision')
EXCEPT
SELECT PlanID
FROM PlanEnrollment pe
WHERE pe.EmployeeID= e.EmployeeID)
简而言之,对于每个员工,这将找到您感兴趣的计划ID列表,减去员工注册的计划。如果减法为空,则表示员工已注册所有计划并且NOT EXISTS将为您返回此员工。
答案 2 :(得分:0)
的 LiveDemo 强>
工作原理:
Employee
表并获取个人数据查询:
WITH cte AS
(
SELECT EmployeeId,
[dental] = SUM(IIF(p.PlanId IS NULL,0, 1)),
[vision] = SUM(IIF(p2.PlanId IS NULL,0, 1)),
[medical] = SUM(IIF(p3.PlanId IS NULL,0, 1))
FROM #PlanEnrollment pe
LEFT JOIN #Plan p
ON pe.PlanId = p.PlanID
AND p.PlanType LIKE 'Dental'
LEFT JOIN #Plan p2
ON pe.PlanId = p2.PlanID
AND p2.PlanType LIKE 'Vision'
LEFT JOIN #Plan p3
ON pe.PlanId = p3.PlanID
AND p3.PlanType LIKE 'Medical'
WHERE GETDATE() >= EnrollmentStartDate
AND GETDATE() <= ISNULL(ErollmentEndDate, '2099-01-01')
GROUP BY EmployeeId
)
SELECT e.FirstName, e.LastName
FROM cte c
JOIN #Employee e
ON c.EmployeeID = e.EmployeeId
WHERE [dental] > 0 AND [vision] > 0 AND [medical] > 0;
数据:
CREATE TABLE #Employee(
EmployeeID INTEGER NOT NULL
,FirstName VARCHAR(90) NOT NULL
,LastName VARCHAR(90) NOT NULL
,Birthdate DATE NOT NULL
,HomeState VARCHAR(20) NOT NULL
,Gender VARCHAR(10) NOT NULL
);
INSERT INTO #Employee(EmployeeID,FirstName,LastName,Birthdate,HomeState,Gender) VALUES (1,'John','Doe','1/1/1978','FL','M');
INSERT INTO #Employee(EmployeeID,FirstName,LastName,Birthdate,HomeState,Gender) VALUES (2,'Jane','Eyre','4/7/1985','AL','F');
INSERT INTO #Employee(EmployeeID,FirstName,LastName,Birthdate,HomeState,Gender) VALUES (3,'Alexander','Hamilton','6/4/1960','NY','M');
INSERT INTO #Employee(EmployeeID,FirstName,LastName,Birthdate,HomeState,Gender) VALUES (4,'Chris','Smith','12/5/1990','CA','M');
INSERT INTO #Employee(EmployeeID,FirstName,LastName,Birthdate,HomeState,Gender) VALUES (5,'Emily','Dickinson','3/5/1945','VT','F');
CREATE TABLE #Plan(
PlanID INTEGER NOT NULL
,PlanType VARCHAR(70) NOT NULL
,PlanName VARCHAR(70) NOT NULL
);
INSERT INTO #Plan(PlanID,PlanType,PlanName) VALUES (1,'Medical','Medical Plan 1');
INSERT INTO #Plan(PlanID,PlanType,PlanName) VALUES (2,'Dental','Dental Plan 1');
INSERT INTO #Plan(PlanID,PlanType,PlanName) VALUES (3,'Vision','Vision Plan 1');
INSERT INTO #Plan(PlanID,PlanType,PlanName) VALUES (4,'Medical','Medical Plan 2');
CREATE TABLE #PlanEnrollment(
EnrollmentID INTEGER NOT NULL PRIMARY KEY
,EmployeeID INTEGER NOT NULL
,PlanID INTEGER NOT NULL
,EnrollmentStartDate DATE NULL
,ErollmentEndDate DATE NULL
);
INSERT INTO #PlanEnrollment(EnrollmentID,EmployeeID,PlanID,EnrollmentStartDate,ErollmentEndDate) VALUES (1,1,1,'1/1/2015','3/1/2015');
INSERT INTO #PlanEnrollment(EnrollmentID,EmployeeID,PlanID,EnrollmentStartDate,ErollmentEndDate) VALUES (2,1,2,'1/1/2014',NULL);
INSERT INTO #PlanEnrollment(EnrollmentID,EmployeeID,PlanID,EnrollmentStartDate,ErollmentEndDate) VALUES (3,2,1,'6/1/2013','5/1/2015');
INSERT INTO #PlanEnrollment(EnrollmentID,EmployeeID,PlanID,EnrollmentStartDate,ErollmentEndDate) VALUES (4,3,4,'2/1/2013',NULL);
INSERT INTO #PlanEnrollment(EnrollmentID,EmployeeID,PlanID,EnrollmentStartDate,ErollmentEndDate) VALUES (5,4,2,'5/3/2015','7/1/2015');
INSERT INTO #PlanEnrollment(EnrollmentID,EmployeeID,PlanID,EnrollmentStartDate,ErollmentEndDate) VALUES (6,1,4,'3/2/2015',NULL);
INSERT INTO #PlanEnrollment(EnrollmentID,EmployeeID,PlanID,EnrollmentStartDate,ErollmentEndDate) VALUES (8,1,3,'3/2/2015',NULL);
答案 3 :(得分:0)
此查询将起作用:
SELECT em.[First Name] as EmployeeFirstName, em.[Last Name] as EmployeeLastName
FROM
(
SELECT pe.EmployeeID, count(DISTINCT p.PlanType) as DistinctPlanTypeCount
FROM
PlanEnrollment pe
JOIN [Plan] p on pe.PlanID = p.PlanID
WHERE
pe.EnrollmentStartDate <= GETDATE() and
(pe.EnrollmentEndDate is NULL or pe.EnrollmentEndDate > GETDATE())
GROUP BY pe.EmployeeID
) Q1
JOIN Employee em ON Q1.EmployeeID = em.EmployeeID
WHERE Q1.DistinctPlanTypeCount = (SELECT count(DISTINCT PlanType) FROM [Plan])
内部查询返回
╔════════════╦═══════════════════════╗
║ EmployeeID ║ DistinctPlanTypeCount ║
╠════════════╬═══════════════════════╣
║ 1 ║ 2 ║
║ 3 ║ 1 ║
╚════════════╩═══════════════════════╝
外部查询按不同的PlanType计数获取Employee列和过滤器。
结果是空集
╔═══════════════════╦══════════════════╗
║ EmployeeFirstName ║ EmployeeLastName ║
╚═══════════════════╩══════════════════╝
答案 4 :(得分:0)
保持简单。
第一个FROM PlanEnrollment过滤所有有医疗计划的员工:
WHERE p1.PlanID in (1,4)
- 其中一项医疗计划
第一个联接将此结果集过滤到拥有Dental的员工
第二个联接将此结果集过滤到具有Vision
第三次加入只是获得对员工的引用,因此您可以列出他们的名字。 SELECT e.*
SELECT e.*
FROM PlanEnrollemnt p1
JOIN PlanEnrollment p2 on p1.EmployeeID = p2.EmployeeId and PlanId = 2 --Dental
JOIN PlanEnrollment p3 on p1.EmployeeID = p3.EmployeeId and PlanId = 3 -- Vison
JOIN Employee e = p1.EmployeeId = e.EmployeeId
WHERE p1.PlanID in (1,4) -- one of the medical plans
答案 5 :(得分:0)
我使用Pivot做到了,并且奏效了。见下文。
SELECT EmployeeFirstName
, EmployeeLastName
FROM
(
SELECT E.FirstName AS EmployeeFirstName
, E.LastName AS EmployeeLastName
, R.EmployeeID
, P.PlanType
FROM PlanEnrollment R INNER JOIN [Plan] P
ON R.PlanID = P.PlanID INNER JOIN Employee E
ON R.EmployeeID = E.EmployeeID
WHERE EnrollmentEndDate IS NULL
AND R.EnrollmentStartDate <= GETDATE()
) SRC PIVOT (COUNT(EmployeeID) FOR PlanType in ([Medical], [Dental], [Vision])) PIVOTTABLE
WHERE Medical > 0
AND Dental > 0
AND Vision > 0;