2010-01-06 12 views
6

Mam następujące zapytanie T-SQL (prosty przypadek testowy) działa poprawnie w MS SQL, ale nie można uzyskać równoważnego zapytania w MS Access (JET-SQL). Problem stanowią dodatkowe kryteria w LEWYM DOŁĄCZU. Jak mogę to zrobić w MS Access?LEWE ŁĄCZENIE na dodatkowych kryteriach w MS Access

T-SQL:

SELECT * FROM A 
LEFT OUTER JOIN B ON A.ID = B.A_ID 
       AND B.F_ID = 3 

JET-SQL (co mam tak daleko, ale zawiesza dostęp!):

SELECT * FROM dbo_A 
LEFT JOIN dbo_B ON (dbo_A.ID = dbo_B.A_ID AND dbo_B.F_ID = 3) 
+0

Nie ma potrzeby stosowania nawiasów w kryterium łączenia –

+0

Czy to ważne, że przykład T-SQL jest złączem zewnętrznym? Cała jego praca polega na zwrocie wszystkich wierszy w A. – Melvin

+0

Kucykach @OMG - Bez nawiasów pojawia się błąd składni, a wraz z nimi Access się zawiesza ... @Melvin - Nie, słowo OUTER jest opcjonalne. – Supergibbs

Odpowiedz

10

Trzeba użyć podselekcji zastosować warunek:

SELECT * 
    FROM dbo_A LEFT JOIN 
    [SELECT dbo_B.* FROM dbo_B WHERE dbo_B.F_ID = 3]. AS dbo_B 
     ON dbo_A.ID = dbo_B.A_ID; 

Jeśli używasz dostępu za pomocą „SQL 92” trybie zgodności włączony, możesz wykonać więcej standard:

SELECT * 
    FROM dbo_A LEFT JOIN 
    (SELECT dbo_B.* FROM dbo_B WHERE dbo_B.F_ID = 3) AS dbo_B 
     ON dbo_A.ID = dbo_B.A_ID; 

Czy potrzebujesz tego do edycji w programie Access? Jeśli nie, po prostu użyj kwerendy przekazującej z natywnym T-SQL. Jeśli tak, prawdopodobnie utworzyłbym widok po stronie serwera, a szczególnie chciałbym przenieść go po stronie serwera, jeśli wartość literalna jest parametryzowana (tj. F_ID = 3 to naprawdę F_ID = N, gdzie N jest wartością wybraną w czasie wykonywania).

Przypisuję te podselekcje wyprowadzonych instrukcji SQL tabeli każdego dnia podczas pracy w programie Access. To nie jest wielka sprawa.

+0

Tak, wiem, że mogę użyć podselekcji, ale jest ona znacznie wolniejsza, więc wolałbym użyć lewego sprzężenia. Nie wiedziałem jednak o opcji pasażu, która działała idealnie! (więcej informacji o innych tutaj: http://support.microsoft.com/kb/303968). Zaznaczam twoją odpowiedź jako zaakceptowaną, ponieważ zadziałało. Dzięki! – Supergibbs

+1

To, czy podselekcja jest wolniejsza, zależy od dwóch rzeczy: 1) w jaki sposób silnik bazy danych uwzględnia optymalizację podselekcji w porównaniu do alternatywnej, a oczywistej w tym przypadku, 2) czy opcja jest dostępna. W języku Jet/ACE SQL nie dzieje się tak dlatego, że nie można zdefiniować łączenia wielu pól w przeciwnym kierunku (tj. Jeden z A => B, a drugi z B => A). Może się zdarzyć, że SQL Server optymalizuje podselekcję podoptymalnie w porównaniu z alternatywą, ale jeśli używasz Jet/ACE, będziesz musiał przestrzegać zasad Jet/ACE, stąd wzmianka o przejściach. –

+1

Jestem prawie pewien, że lewe połączenie jest zawsze szybsze niż podselekcja. Jasne, w małym zbiorze danych lub jeśli twój silnik DB może zoptymalizować (AKA zmieni twoją podselekcję w lewe połączenie), nie zobaczysz różnicy, ale "lewe połączenie, a następnie wybór n wierszy" będzie szybsze niż " n + 1 wybiera ". Zdecydowanie w moim przypadku SQL Server uruchomił lewe dołączenie szybciej. – Supergibbs

-4

Ten ostatni warunek nie jest technicznie przyłączyć ale porównanie do dosłowności. Umieścić go w klauzuli WHERE:

SELECT * 
FROM a LEFT OUTER JOIN b ON a.ID = b.a_id 
WHERE b.f_id = 3; 
+5

To nie prawda. Sprawdzenie F_ID = 3 w warstwie łączenia po lewej daje wartość null dla wszystkich wartości od B, gdy F_ID = 3. Umieszczenie go w klauzuli where nie zwróci ich wcale. – lins314159

+0

Przykro mi, ale chodziło mi o to, że otrzymasz zero, gdy F_ID <> 3 dla lewego sprzężenia. – lins314159

1

Czy dostajesz komunikat o błędzie, gdy się zawiesi, czy też po prostu zamknąć? Sądząc po nazwie dbo_B, odgadnę, że są to połączone tabele w programie Access. Wierzę, że kiedy robisz takie sprzężenie, Access nie informuje serwera SQL, że potrzebuje wyniku dołączenia, mówi "Daj mi wszystkie wiersze obu tabel", a następnie próbuje je połączyć. Jeśli tabele są bardzo duże, może to spowodować zablokowanie aplikacji.

Prawdopodobnie lepiej jest stworzyć widok na SQL Server, aby uzyskać to, czego potrzebujesz.

+0

Zdecydowanie dobry pomysł, czy to oznacza, że ​​moja składnia jest poprawna, po prostu program Access nie może sobie z tym poradzić? – Supergibbs

+0

Nie wiem, czy sam Access ma ograniczenie techniczne, ale jeśli tabele są milionami wierszy, to komputer, na którym działa program Access, a także sieć, w której przepływają dane, jest prawdopodobnie przytłoczony. –

+0

To nieprawda, że ​​Jet/ACE prosi o pełną tabelę i robi same połączenia, chyba że jest coś, co uniemożliwia Jet/ACE uzyskanie metadanych potrzebnych do ustalenia, czy może przekazać całość na serwer (co powinno być w 99% przypadków). Możliwe też, że jest coś w połączonych tabelach (na przykład w widokach), które uniemożliwiają wykonanie pracy przez Jet/ACE. Są to jedyne przypadki, o których mogę pomyśleć, które mogą spowodować, że Jet/ACE zażąda pełnych tabel z dostarczonym SQL.Krótko mówiąc, jest to bardzo, bardzo mało prawdopodobne, że tak się stanie. –