Sql LEFT OUTER JOIN with WHERE clause

前端 未结 6 387
生来不讨喜
生来不讨喜 2020-12-10 17:01

I have two tables:

Request:

 RequestID | Msg
----------------
    5  | abc
    6  | def
    7  | ghi
    8  | jkl

相关标签:
6条回答
  • 2020-12-10 17:07

    Move the constraint to your on clause.

    select *
    from request r
    left join requestStatus rs
    on r.requestID = rs.requestID
    --and status_id = 1
    and status_id <> 2
    

    What's happening to you is that the outer join is performed first. Any rows coming from the outer join that don't have matches will have nulls in all the columns. Then your where clause is applied, but since 1 <> null, it's not going to work like you want it to.

    EDIT: Changed on clause based on Piyush's comment.

    0 讨论(0)
  • 2020-12-10 17:07

    SqlFiddle

    This answer assumes you just want the RequestId & Msg from the Request Table where there is not a record in the RequestStatus table with that RequestId and a StatusId of 2.

    You won't get extra records for Requests with multiple RequestStatus records using this query either (vs Left join).

    Using the not exists clause is faster than Except, Not In, Outer Apply, etc in this article by Aaron Bertrand - Should I use NOT IN, OUTER APPLY, LEFT OUTER JOIN, EXCEPT, or NOT EXISTS?

    select r.RequestId, r.Msg
      from Request r
      where not exists (
        select 1 
        from RequestStatus rs 
        where rs.StatusId = 2
          and rs.RequestId = r.RequestId
        )
    
    0 讨论(0)
  • 2020-12-10 17:16

    The answer is pretty simple, use left join but filter on the rows that have StatusId different than 2, like so:

    select *
    from request r
    left join requestStatus rs
    on r.requestID = rs.requestID
    where rs.StatusId <> 2 or rs.StatusId IS NULL
    

    EDIT: added or rs.StatusId IS NULL additional condition to also include rows in requestStatus table that don't have a match in request table.

    0 讨论(0)
  • 2020-12-10 17:23

    Try this

    SELECT *
    FROM Request R
      LEFT JOIN RequestStatus RS ON R.RequestID  =  RS.RequestID   
      WHERE RS.StatusID <> 2 OR RS.RequestID IS NULL
    

    SQL FIDDLE

    0 讨论(0)
  • 2020-12-10 17:27

    In SQL Server 2017 you can put AND after ON in this way

    SELECT * FROM Request
    LEFT OUTER JOIN RequestStatus ON Request.RequestID = RequestStatus.RequestID
    AND RequestStatus.StatusID <> 2
    WHERE Request.RequestID IS NOT NULL
    
    0 讨论(0)
  • 2020-12-10 17:31

    You need use an NOT IN Query Statement like this

    Select * 
    From Request 
    Where RequestID not in 
        (Select RequestID 
        From RequestStatus 
        Where StatusID = 2)
    

    or

    Select * 
    From Request r 
    left join requestStatus rs on r.requestID = rs.requestID 
    Where r.RequestID not in 
        (Select RequestID 
        From RequestStatus 
        Where StatusID = 2)
    
    0 讨论(0)
提交回复
热议问题