[英]Joining three tables with separate sets of identifying columns
I have three tables that share one field with another table, so: 我有三个表与另一个表共享一个字段,所以:
Employee_Data: EMP_ID, PHONE_EXTENSION
Outage_Data: DATE, EMP_ID
Phone_Data: DATE, PHONE_EXTENSION
I need to combine data where the agent data is matched with data in the other two tables. 我需要合并代理数据与其他两个表中的数据相匹配的数据。 Basically, I need to combine the data from
Outage_data
and Phone_data
(because it is all grouped by date) with Employee_Data
as the "bridge". 基本上,我需要将
Outage_data
和Phone_data
的数据(因为它们都按日期分组)与Employee_Data
为“桥梁”。
I already have my SELECT and everything laid out like it needs to be; 我已经有了我的SELECT,一切都需要布置。 I just need help with the join.
我只需要加入的帮助。
EDIT By Request, here is the full query. 按要求编辑 ,这是完整的查询。 I tried not to do this for simplicity's sake:
为了简单起见,我尝试不这样做:
With Epi AS
(SELECT EMP_ID, PHONE_EXTENSION, Name, Manager, EWFMDeptname, Location From Employee_Data)
,
Shrink AS
(SELECT DATE, EMP_ID, START_MOMENT, STOP_MOMENT, SEG_CODE FROM Outage_Data)
,
OutIn AS
(SELECT date, logid, login, logout From PHONE_DATA)
SELECT
ISNULL(Shrink.DATE,OutIn.DATE) AS RowDate,
ISNULL(Epi.EMP_ID,RTRIM(LTRIM(Shrink.EMP_ID))) AS Badge,
ISNULL(Epi.PHONE_EXTENSION, OutIn.logid) AS [ACD/Extension],
Epi.Name,
Epi.Manager,
Epi.EWFMDeptName,
Epi.Location,
ISNULL(Shrink.START_MOMENT, (SELECT Shrink.START_MOMENT FROM Shrink WHERE SHRINK.SEG_CODE = 'SHIFT' AND Shrink.EMP_ID = EPI.EMP_ID AND SHRINK.DATE = OutIn.DATE)) AS ShiftStart,
ISNULL(Shrink.STOP_MOMENT, (SELECT Shrink.STOP_MOMENT FROM Shrink WHERE SHRINK.SEG_CODE = 'SHIFT' AND Shrink.EMP_ID = EPI.EMP_ID AND SHRINK.DATE = OutIn.row_date)) AS ShiftStop,
OutIn.login AS Login,
OutIn.logout AS Logout,
Shrink.SEG_CODE AS OUTSEG,
IIF(Shrink.SEG_CODE = 'PABS' OR Shrink.SEG_CODE = 'UABS' OR Shrink.SEG_CODE = 'PPBA' OR Shrink.SEG_CODE = 'UPBA' OR Shrink.SEG_CODE = 'VACA' OR Shrink.SEG_CODE = 'JURY' OR Shrink.SEG_CODE = 'GOVT' OR Shrink.SEG_CODE = 'LOA' OR Shrink.SEG_CODE = 'BRVMNT' OR Shrink.SEG_CODE = 'FH', Shrink.START_MOMENT, NUll) AS OutStart,
IIF(Shrink.SEG_CODE = 'PABS' OR Shrink.SEG_CODE = 'UABS' OR Shrink.SEG_CODE = 'PPBA' OR Shrink.SEG_CODE = 'UPBA' OR Shrink.SEG_CODE = 'VACA' OR Shrink.SEG_CODE = 'JURY' OR Shrink.SEG_CODE = 'GOVT' OR Shrink.SEG_CODE = 'LOA' OR Shrink.SEG_CODE = 'BRVMNT' OR Shrink.SEG_CODE = 'FH', Shrink.STOP_MOMENT, NUll) AS OutStop,
IIF(DateADD(minute, 5, Shrink.START_MOMENT) < OutIn.Login, CONVERT(decimal(10,2), DATEDIFF(second ,Shrink.START_MOMENT,OutIn.Login)/60.0) ,0.00) AS Late,
ISNULL(IIF(Convert(decimal(10,2), DATEDIFF(second, Shrink.STOP_MOMENT, OutIn.logout)/60.0) = NULL OR Convert(decimal(10,2), DATEDIFF(second, Shrink.STOP_MOMENT, OutIn.logout)/60.0) > 0.00, 0.00, ABS(Convert(decimal(10,2), DATEDIFF(second, Shrink.STOP_MOMENT, OutIn.logout)/60.0))), 0.00) AS [Left],
IIF(OutIn.login IS NULL AND Shrink.SEG_CODE = 'SHIFT' ,DATEDIFF(minute,Shrink.START_MOMENT, Shrink.STOP_MOMENT), 0.00) AS NCNS
FROM (Epi Right JOIN Shrink on Epi.EMP_ID = Shrink.EMP_ID) INNER JOIN OutIn ON (Shrink.DATE = OutIn.DATE) JOIN (
WHERE Shrink.SEG_CODE = 'PABS' OR Shrink.SEG_CODE = 'UABS' OR Shrink.SEG_CODE = 'PPBA' OR Shrink.SEG_CODE = 'UPBA' OR Shrink.SEG_CODE = 'VACA' OR Shrink.SEG_CODE = 'JURY' OR Shrink.SEG_CODE = 'GOVT' OR Shrink.SEG_CODE = 'LOA' OR Shrink.SEG_CODE = 'BRVMNT' OR Shrink.SEG_CODE = 'FH' or Shrink.SEG_CODE = 'SHIFT'
ORDER BY Badge;
Sorry its kind of messy. 对不起,它有点混乱。 Again, Thank you
再次谢谢你
EDIT2 编辑2
Per request, here is some of my data: 根据请求,以下是我的一些数据:
Shrink: 收缩:
EMP_SK EMP_ID EMP_LAST_NAME EMP_FIRST_NAME EMP_SORT_NAME EMP_SHORT_NAME EMP_SENIORITY EMP_EFF_HIRE_DATE NOM_DATE SEG_CODE START_MOMENT STOP_MOMENT
-9.88181E+11 73485 BLAH BLAH BLAH BLAH 20130812000 8/12/2013 0:00:00 10/6/2013 0:00:00 SHIFT 10/6/2013 12:00:00 10/6/2013 21:00:00
-9.88181E+11 73485 BLAH BLAH BLAH BLAH 20130812000 8/12/2013 0:00:00 10/7/2013 0:00:00 SHIFT 10/7/2013 12:00:00 10/7/2013 21:00:00
-9.88768E+11 192329 BLAH BLAH BLAH BLAH 20130715000 7/15/2013 0:00:00 10/7/2013 0:00:00 SHIFT 10/7/2013 6:00:00 10/7/2013 15:00:00
-9.88741E+11 224579 BLAH BLAH BLAH BLAH 20091214000 12/14/2009 0:00:00 10/7/2013 0:00:00 SHIFT 10/7/2013 8:00:00 10/7/2013 17:00:00
-9.88741E+11 224579 BLAH BLAH BLAH BLAH 20091214000 12/14/2009 0:00:00 10/8/2013 0:00:00 SHIFT 10/8/2013 8:00:00 10/8/2013 17:00:00
-9.88181E+11 73485 BLAH BLAH BLAH BLAH 20130812000 8/12/2013 0:00:00 10/8/2013 0:00:00 SHIFT 10/8/2013 12:00:00 10/8/2013 21:00:00
-9.88768E+11 192329 BLAH BLAH BLAH BLAH 20130715000 7/15/2013 0:00:00 10/8/2013 0:00:00 SHIFT 10/8/2013 6:00:00 10/8/2013 15:00:00
Epi: Epi:
Badge Name NT Login Email MBadge Manager Vendor Business Unit Business Unit Desc Sub-Support Name Segment Location Subqueue Phone Queue Title EWFMDeptCode EWFMDeptName EWFMTeamCode EWFMTeamName ACD/Extension Switch Name DomsID DomsID2 DomsID3 Tech-ID (DPS) Tech-ID2 (DPS2) KanaUserID NetAgentID Part_Time Alias Miscellaneous Hiredate Cost Center Jack Building QueueStatus Training Class Trainer TeamCodeName TeamCodeAbbr
73485 blah blah blah 315413 blah blah blah Service Desk Delivery blah Tech Support blah blah Client Specialty Queue Phone Agent blah blah Not Assigned Not Assigned 4341776 AC03 NULL NULL NULL NULL NULL NULL NULL 0 NULL NULL 00:00.0 blah blah blah Normal Generic Class Instructor Not Assigned Not Assigned
224579 blah blah blah 626985 blah blah blah Service Desk Delivery blah Tech Support blah blah Client Specialty Queue Phone Agent blah blah Not Assigned Not Assigned 4341991 AC03 NULL NULL NULL 211212 NULL 0 0 0 NULL NULL 00:00.0 blah blah blah Normal Generic Class Instructor Not Assigned Not Assigned
192329 blah blah blah 364970 blah blah blah Service Desk Delivery blah Tech Support blah blah Client Specialty Queue Phone Agent blah blah Not Assigned Not Assigned 4341937 AC03 NULL NULL NULL NULL NULL 0 0 0 NULL NULL 00:00.0 blah blah blah Normal Generic Class Instructor Not Assigned Not Assigned
OutIn: OutIn:
row_date logid login logout
10/6/2013 0:00:00 4341776 10/6/2013 12:00:15 10/6/2013 21:00:26
10/7/2013 0:00:00 4341937 10/7/2013 6:04:48 10/7/2013 15:15:22
10/7/2013 0:00:00 4341991 10/7/2013 7:54:34 10/7/2013 17:00:39
10/7/2013 0:00:00 4341776 10/7/2013 12:00:16 10/7/2013 21:20:36
10/8/2013 0:00:00 4341937 10/8/2013 5:59:47 10/8/2013 15:01:31
10/8/2013 0:00:00 4341991 10/8/2013 7:58:46 10/8/2013 17:03:26
10/8/2013 0:00:00 4341776 10/8/2013 12:00:10 10/8/2013 14:32:20
10/8/2013 0:00:00 4341776 10/8/2013 14:32:20 10/8/2013 21:00:04
Thank you again 再次感谢你
Final EDIT 最终编辑
I finally figured it out. 我终于弄明白了。 Here is the completed code:
这是完整的代码:
SELECT
a.NOM_DATE AS RowDate,
a.EMP_ID AS Badge,
ISNULL(a.[Extension], a.logid) AS [Extension],
a.Name,
a.Manager,
a.DeptName,
a.Location,
a.START_MOMENT AS ShiftStart,
a.STOP_MOMENT AS ShiftStop,
a.login AS Login,
a.logout AS Logout,
a.SEG_CODE AS OUTSEG,
IIF(a.SEG_CODE = 'PABS' OR a.SEG_CODE = 'UABS' OR a.SEG_CODE = 'PPBA' OR a.SEG_CODE = 'UPBA' OR a.SEG_CODE = 'VACA' OR a.SEG_CODE = 'JURY' OR a.SEG_CODE = 'GOVT' OR a.SEG_CODE = 'LOA' OR a.SEG_CODE = 'BRVMNT' OR a.SEG_CODE = 'FH', a.START_MOMENT, NUll) AS OutStart,
IIF(a.SEG_CODE = 'PABS' OR a.SEG_CODE = 'UABS' OR a.SEG_CODE = 'PPBA' OR a.SEG_CODE = 'UPBA' OR a.SEG_CODE = 'VACA' OR a.SEG_CODE = 'JURY' OR a.SEG_CODE = 'GOVT' OR a.SEG_CODE = 'LOA' OR a.SEG_CODE = 'BRVMNT' OR a.SEG_CODE = 'FH', a.STOP_MOMENT, NUll) AS OutStop,
IIF(DateADD(minute, 5, a.START_MOMENT) < a.Login, CONVERT(decimal(10,2), DATEDIFF(second ,a.START_MOMENT,a.Login)/60.0) ,0.00) AS Late,
ISNULL(IIF(Convert(decimal(10,2), DATEDIFF(second, a.STOP_MOMENT, a.logout)/60.0) = NULL OR Convert(decimal(10,2), DATEDIFF(second, a.STOP_MOMENT, a.logout)/60.0) > 0.00, 0.00, ABS(Convert(decimal(10,2), DATEDIFF(second, a.STOP_MOMENT, a.logout)/60.0))), 0.00) AS [Left],
IIF(a.login IS NULL AND a.SEG_CODE = 'SHIFT' ,DATEDIFF(minute,a.START_MOMENT, a.STOP_MOMENT), 0.00) AS NCNS
FROM (SELECT l.row_date, l.logid, l.[login], l.logout, f.NOM_DATE, f.EMP_ID, f.START_MOMENT, f.STOP_MOMENT, f.SEG_CODE,
f.Badge, f.Extension, f.Name, f.Manager, f.Deptname, f.Location FROM LogInOutActual l
right Join
(SELECT NOM_DATE, RTRIM(LTRIM(EMP_ID)) as EMP_ID, START_MOMENT, STOP_MOMENT, SEG_CODE, Badge,
Extension, Name, Manager, Deptname, Location FROM Shrink_Raw
LEFT OUTER JOIN Epicenter ON Shrink_Raw.EMP_ID = Epicenter.Badge
WHERE Shrink_Raw.SEG_CODE = 'PABS' OR Shrink_Raw.SEG_CODE = 'UABS' OR Shrink_Raw.SEG_CODE = 'PPBA'
OR Shrink_Raw.SEG_CODE = 'UPBA' OR Shrink_Raw.SEG_CODE = 'VACA' OR Shrink_Raw.SEG_CODE = 'JURY'
OR Shrink_Raw.SEG_CODE = 'GOVT' OR Shrink_Raw.SEG_CODE = 'LOA' OR Shrink_Raw.SEG_CODE = 'BRVMNT'
OR Shrink_Raw.SEG_CODE = 'FH' or Shrink_Raw.SEG_CODE = 'SHIFT') as f
on l.row_date = f.NOM_DATE AND l.logid = f.[ACD/Extension]) as a
WHERE Extension IS NOT NULL AND Name IS NOT NULL AND Manager IS NOT NULL and DeptName IS NOT NULL AND Location IS NOT NULL
ORDER BY RowDate, Badge;
After sleeping on it, I realized what to do. 睡了之后,我意识到该怎么办。 I did one join in a subquery and then another join in another subquery.
我在一个子查询中执行了一个联接,然后在另一个子查询中进行了另一个联接。 It was so simple I feel stupid for posting it.
太简单了,我觉得发布它很愚蠢。 Thank you to everyone that help the thinking process!
感谢所有对思考过程有帮助的人!
Select * from employee_data e
join outage_data d on e.emp_id = d.emp_id
join phone_data p on d.date = p.date
Your query looks mostly fine assuming you mean the RIGHT JOIN on Shrink so you don't miss any rows that don't have a matching Employee_Data row. 假设您的意思是在Shrink上进行RIGHT JOIN,则查询看起来很好,因此您不会错过任何没有匹配的Employee_Data行的行。 There's just an extraneous
JOIN (
at the end of your FROM
clause that I removed: 我删除的
FROM
子句的末尾只有一个多余的JOIN (
With Epi AS
(SELECT EMP_ID, PHONE_EXTENSION, Name, Manager, EWFMDeptname, Location From Employee_Data)
,
Shrink AS
(SELECT DATE, EMP_ID, START_MOMENT, STOP_MOMENT, SEG_CODE FROM Outage_Data)
,
OutIn AS
(SELECT date, logid, login, logout From PHONE_DATA)
SELECT
-- These fields are always the same because of the inner join,
-- no need to check for nulls
-- ISNULL(Shrink.DATE,OutIn.DATE) AS RowDate,
Shrink.DATE AS RowDate,
-- These fields are always the same because of the right join
-- unless there is no matching Epi row, then Epi.EMP_ID will
-- be null. You can just use Shrink.EMP_ID. If this field
-- really needs to be trimmed, then we should be trimming
-- this field in the RIGHT JOIN clause as well.
-- ISNULL(Epi.EMP_ID,RTRIM(LTRIM(Shrink.EMP_ID))) AS Badge,
Shrink.EMP_ID AS Badge,
ISNULL(Epi.PHONE_EXTENSION, OutIn.logid) AS [ACD/Extension],
Epi.Name,
Epi.Manager,
Epi.EWFMDeptName,
Epi.Location,
-- I've added an alias to Shrink in the subqueries
-- to help clarify what is getting filtered.
-- I also changed the where clause in the subquery
-- a bit so give this a try.
-- If these are the problem fields, try not doing the
-- subqueries so you can get the actual data in the rows,
-- and mess around with just the subquery using values
-- from the original rows until you get the right START_MOMENT/STOP_MOMENT
ISNULL(Shrink.START_MOMENT, (SELECT Shrink.START_MOMENT FROM Shrink s WHERE s.SEG_CODE = 'SHIFT' AND s.EMP_ID = Shrink.EMP_ID AND s.DATE = Shrink.DATE)) AS ShiftStart,
ISNULL(Shrink.STOP_MOMENT, (SELECT Shrink.STOP_MOMENT FROM Shrink s WHERE s.SEG_CODE = 'SHIFT' AND s.EMP_ID = Shrink.EMP_ID AND s.DATE = Shrink.DATE)) AS ShiftStop,
OutIn.login AS Login,
OutIn.logout AS Logout,
Shrink.SEG_CODE AS OUTSEG,
IIF(Shrink.SEG_CODE = 'PABS' OR Shrink.SEG_CODE = 'UABS' OR Shrink.SEG_CODE = 'PPBA' OR Shrink.SEG_CODE = 'UPBA' OR Shrink.SEG_CODE = 'VACA' OR Shrink.SEG_CODE = 'JURY' OR Shrink.SEG_CODE = 'GOVT' OR Shrink.SEG_CODE = 'LOA' OR Shrink.SEG_CODE = 'BRVMNT' OR Shrink.SEG_CODE = 'FH', Shrink.START_MOMENT, NUll) AS OutStart,
IIF(Shrink.SEG_CODE = 'PABS' OR Shrink.SEG_CODE = 'UABS' OR Shrink.SEG_CODE = 'PPBA' OR Shrink.SEG_CODE = 'UPBA' OR Shrink.SEG_CODE = 'VACA' OR Shrink.SEG_CODE = 'JURY' OR Shrink.SEG_CODE = 'GOVT' OR Shrink.SEG_CODE = 'LOA' OR Shrink.SEG_CODE = 'BRVMNT' OR Shrink.SEG_CODE = 'FH', Shrink.STOP_MOMENT, NUll) AS OutStop,
IIF(DateADD(minute, 5, Shrink.START_MOMENT) < OutIn.Login, CONVERT(decimal(10,2), DATEDIFF(second ,Shrink.START_MOMENT,OutIn.Login)/60.0) ,0.00) AS Late,
ISNULL(IIF(Convert(decimal(10,2), DATEDIFF(second, Shrink.STOP_MOMENT, OutIn.logout)/60.0) = NULL OR Convert(decimal(10,2), DATEDIFF(second, Shrink.STOP_MOMENT, OutIn.logout)/60.0) > 0.00, 0.00, ABS(Convert(decimal(10,2), DATEDIFF(second, Shrink.STOP_MOMENT, OutIn.logout)/60.0))), 0.00) AS [Left],
IIF(OutIn.login IS NULL AND Shrink.SEG_CODE = 'SHIFT' ,DATEDIFF(minute,Shrink.START_MOMENT, Shrink.STOP_MOMENT), 0.00) AS NCNS
FROM (Epi Right JOIN Shrink on Epi.EMP_ID = Shrink.EMP_ID) INNER JOIN OutIn ON (Shrink.DATE = OutIn.DATE)
WHERE Shrink.SEG_CODE = 'PABS' OR Shrink.SEG_CODE = 'UABS' OR Shrink.SEG_CODE = 'PPBA' OR Shrink.SEG_CODE = 'UPBA' OR Shrink.SEG_CODE = 'VACA' OR Shrink.SEG_CODE = 'JURY' OR Shrink.SEG_CODE = 'GOVT' OR Shrink.SEG_CODE = 'LOA' OR Shrink.SEG_CODE = 'BRVMNT' OR Shrink.SEG_CODE = 'FH' or Shrink.SEG_CODE = 'SHIFT'
ORDER BY Badge;
SELECT *
FROM Employee_Data ED
INNER JOIN Phone_Data PD ON
ED.PHONE_EXTENSION = PD.PHONE_EXTENSION
INNER JOIN Outage_Data OD ON
ED.EMP_ID = OD.EMP_ID
Without seeing what your SELECT statement looks like, here's something that will return the complete table data: 没有看到您的SELECT语句的样子,这是将返回完整表数据的内容:
SELECT *
FROM Employee_Data E
JOIN Outage_Data O on E.EMP_ID = O.EMP_ID
JOIN Phone_Data P on P.DATE = O.DATE
ORDER By P.DATE
You can adjust as needed. 您可以根据需要进行调整。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.