Zdarzyło mi się to w tworzonej aplikacji. Tam problem rozwiązałem inaczej - to co robiłem nie było najlepszym pomysłem, ale i tak dziwi mnie to, co wtedy mi wyszło. W aplikacji miałem do czynienia z około milionem rekordów. Na potrzeby tego wątku przygotowałem znacznie prostszy przykład. Ale nie dopatrujcie się w nim jakiejś logiki.
M$ SQL 2012 EN. Tworzę tabelę. Prostą. Dopisuję dwa rekordy - wystarczy, aby pokazać. Sprawdzam zwykłym SELECT
co mam w tabeli i robię pierwszego 'LEFT JOIN', który zresztą daje mi takie rezultaty, jakich się spodziewałem - mam tylko rekordy z "lewej" tabeli. Modyfikuję tego 'JOIN' i niespodzianka - z lewej, dwurekordowej tabeli wchodzi tylko jeden rekord! A gdzie drugi?
Kod:
DECLARE @A TABLE (ROW_NO int, STAT int)
INSERT INTO @A VALUES(1, 1)
INSERT INTO @A VALUES(2, 1)
SELECT * FROM @A
SELECT a1.ROW_NO AS ROW_NO1, a2.ROW_NO AS ROW_NO2, a1.STAT as STAT1, a2.STAT AS STAT2
FROM @A AS a1
LEFT JOIN @A AS a2 ON a1.ROW_NO + 1 = a2.ROW_NO and (a1.STAT = 1) AND ((a2.STAT = 2) or (a2.STAT IS NULL))
WHERE (a1.STAT = 1) AND ((a2.STAT = 2) or (a2.STAT IS NULL))
SELECT a1.ROW_NO AS ROW_NO1, a2.ROW_NO AS ROW_NO2, a1.STAT as STAT1, a2.STAT AS STAT2
FROM @A AS a1
LEFT JOIN @A AS a2 ON a1.ROW_NO + 1 = a2.ROW_NO --and (a1.STAT = 1) AND ((a2.STAT = 2) or (a2.STAT IS NULL))
WHERE (a1.STAT = 1) AND ((a2.STAT = 2) or (a2.STAT IS NULL))
i wyniki:
ROW_NO | STAT |
---|---|
1 | 1 |
2 | 1 |
to, czego oczekiwałem:
ROW_NO1 | ROW_NO2 | STAT1 | STAT2 |
---|---|---|---|
1 | NULL | 1 | NULL |
2 | NULL | 1 | NULL |
oraz to, czego nie rozumiem:
ROW_NO1 | ROW_NO2 | STAT1 | STAT2 |
---|---|---|---|
1 | NULL | 1 | NULL |
2 | NULL | 1 | NULL |
Nie rozumiem tego - do tej pory myślałem, że rekordy z "lewej" tabeli przechodzą. A warunek drugiego LEFT JOIN
jest przecież mniej restrykcyjny.