如何从SQL Join获取匹配和不匹配的行

时间:2014-06-23 10:03:37

标签: c# sql .net sql-server join

我有两个表连接,我想要一个显示所有匹配和非匹配行的结果。是否可以在SQL中使用?

这些是表格和查询...

 CREATE TABLE #Day (id int, EID int, PID varchar(10), [Day] int, Shift varchar(10))
 CREATE TABLE #Night (id int, EID int, PID varchar(10), [Day] int, Shift varchar(10))

 INSERT INTO #Day 
 SELECT Atten_ID, EID, PID, DATEPART(DD,in_time) AS [Day], shift
   FROM Attendance
  WHERE (shift = 'D')

 INSERT INTO #Night 
 SELECT Atten_ID, EID, PID, DATEPART(DD,in_time) AS [Day], shift
   FROM Attendance
  WHERE (shift = 'N')

 SELECT #Day.EID, #Day.PID, #Day.Day, #Day.Shift AS DShift, #Night.Shift AS NShift 
   FROM #Day
        JOIN #Night ON #Day.EID = #Night.EID
                   AND #Day.PID = #Night.PID
                   AND #Day.Day = #Night.Day

结果应该是这样......

EID |  PID  | Day | DShift   | NShift
______________________________________
100 |  S001 |  01 |  D       |   N
100 |  S001 |  02 |  D       |   -
100 |  S001 |  03 |  -       |   N

3 个答案:

答案 0 :(得分:2)

也许使用FULL OUTER JOIN

 SELECT COALESCE(d.EID,n.EID),
        COALESCE(d.PID,n.PID),
        COALESCE(d.Day,n.Day),
        d.Shift AS DShift,
        n.Shift AS NShift 
   FROM #Day d
        FULL JOIN #Night n ON d.EID = n.EID AND d.PID = n.PID AND d.Day = n.Day

答案 1 :(得分:1)

除了Sheen的答案之外,还有几点说明:

left join将显示左表中的所有行,以及右表中的匹配行。

full join将显示两个表中的所有行。

请参阅A Visual Explanation of SQL Joins

在回复您的评论时,您可以使用case。这允许您在不同条件下返回不同的值:

select  ...
,       case 
        when d.Shift is not null and n.Shift is not null then 'D/N'
        when d.Shift is not null then 'D'
        when d.Shift is not null then 'N'
        else '-'
        end as NorD

答案 2 :(得分:1)

实际上,你不需要临时表,只需要CTE。而且,您可以使用CASE来实现D/N结果:

 WITH vDAY as ( SELECT Atten_ID, EID, PID, DATEPART(DD,in_time) AS [Day], shift
   FROM Attendance
  WHERE (shift = 'D')
 ),
 vNIGHT as (
 SELECT Atten_ID, EID, PID, DATEPART(DD,in_time) AS [Day], shift
   FROM Attendance
  WHERE (shift = 'N')
 )
 SELECT COALESCE(d.EID,n.EID),
    COALESCE(d.PID,n.PID),
    COALESCE(d.Day,n.Day),
    CASE 
      WHEN d.Shift='D' and n.Shift='N' 
        then 'D/N'
      WHEN d.Shift IS NOT NULL then d.Shift
      ELSE COALESCE( d.Shift, '-' ) END
       AS DShift,
    CASE WHEN d.Shift='D' and n.Shift='N'
       then 'D/N' else COALESCE( n.Shift, '-' ) end
       AS NShift 
 FROM vDay d
    FULL JOIN vNight n ON 
       d.EID = n.EID AND d.PID = n.PID AND d.Day = n.Day