Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Klauzula WHERE vs ON podczas korzystania z funkcji JOIN

Tylko uważaj na różnicę z połączeniami zewnętrznymi. Zapytanie, w którym filtr b.IsApproved (w prawej tabeli, Bar) jest dodany do ON warunek JOIN :

SELECT * 
FROM Foo f 
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId); 

Jest NIE tak samo jak umieszczenie filtra w WHERE klauzula:

SELECT * 
FROM Foo f 
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1); 

Ponieważ dla 'failed' zewnętrznych łączy do Bar (tzn. tam, gdzie nie ma b.BarId dla f.BarId ), spowoduje to pozostawienie b.IsApproved jako NULL dla wszystkich takich nieudanych wierszy sprzężenia, a następnie zostaną one odfiltrowane.

Innym sposobem patrzenia na to jest to, że dla pierwszego zapytania LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId) zawsze zwróci LEFT wiersze tabeli, ponieważ LEFT OUTER JOIN gwarantuje, że LEFT wiersze tabeli zostaną zwrócone, nawet jeśli łączenie się nie powiedzie. Jednak efekt dodania (b.IsApproved = 1) do LEFT OUTER JOIN warunkiem jest NULL wszystkich prawych kolumn tabeli, gdy (b.IsApproved = 1) jest fałszywe, tj. zgodnie z tymi samymi zasadami, które zwykle stosuje się do LEFT JOIN warunek na (b.BarId = f.BarId) .

Aktualizacja :Aby uzupełnić pytanie zadane przez Conrada, odpowiednikiem LOJ dla filtra OPCJONALNEGO byłoby:

SELECT * 
FROM Foo f 
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);

czyli WHERE Klauzula musi uwzględniać oba warunki, czy łączenie się nie powiedzie (NULL) a filtr ma zostać zignorowany, a gdzie łączenie się powiedzie, a filtr musi zostać zastosowany. (b.IsApproved lub b.BarId można przetestować pod kątem NULL )

Umieściłem tutaj SqlFiddle, który pokazuje różnice między różnymi miejscami b.IsApproved filtr względem JOIN .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak naprawić komunikat o błędzie 7325 w programie SQL Server:„Obiekty eksponujące kolumny z typami CLR nie są dozwolone w kwerendach rozproszonych”

  2. Różnica w obsłudze przestrzeni między Oracle a SQL Server

  3. Przegląd typów złączeń SQL wraz z przykładami

  4. Jak wykonać LEFT ANTI SEMI JOIN w SQL Server

  5. Czy można określić warunek w Count()?