2012-05-02 38 views
4

是否可以執行SQL查詢,從左表中獲取一些信息,並從右表中獲取匹配條件的所有信息。 但如果沒有記錄匹配的右表中的條件,應該還是顯示完整的記錄,但充斥着大量的* NULL * SSQL右外部連接在右表中沒有匹配

此刻,我得出這樣的:

select 
u.id, u.fullname, 
r.* 
from 
users as u 
right outer join 
rapports as r 
on 
u.id = r.userid 
where 
u.active = 1 
and (r.closed = 0 or CONVERT(varchar, r.periodstart, 112) = convert(varchar, GETDATE(), 112)) 
order by 
u.fullname 

但是這隻顯示user-table的記錄,如果rapports-table中有與WHERE相匹配的記錄條件。

無論如何可能嗎?

+0

如果你想從左邊的表(第一)表,你應該使用LEFT OUTER JOIN。我很少在實踐中看到正確的外連接,因爲它們在邏輯上考慮很不直觀。恕我直言。 –

+0

是的,但這仍然不能解決問題:( – Behrens

回答

2

通知,其中用於外部表(R)的條件去 - 不在WHERE子句中(將外連接轉換爲內連接),而是在ON子句中。

select 
u.id, u.fullname, 
r.* 
from 
users as u 
left outer join 
rapports as r 
on 
u.id = r.userid 
and (r.closed = 0 
    or CONVERT(varchar, r.periodstart, 112) = convert(varchar, GETDATE(), 112)) 
where 
u.active = 1 
order by 
u.fullname; 

然而,這是好多了:

select 
u.id, u.fullname, 
r.* 
from 
users as u 
left outer join 
rapports as r 
on 
u.id = r.userid 
and (r.closed = 0 or CONVERT(DATE, r.periodstart) = CONVERT(DATE, GETDATE())) 
where 
u.active = 1 
order by 
u.fullname; 
+0

完美!謝謝! :) – Behrens

1

是的!

變化right outer join通過left outer join

select 
u.id, u.fullname, 
r.* 
from 
users as u 
left outer join 
rapports as r 
on 
u.id = r.userid 
where 
u.active = 1 
and (r.closed = 0 or CONVERT(varchar, r.periodstart, 112) = convert(varchar, GETDATE(), 112)) 
order by 
u.fullname 

左外連接邏輯運算返回每個行,其滿足 聯接與第二(底部)輸入的第一(頂部)輸入的。它 還會返回第一個輸入中第二個輸入中沒有匹配行 的任何行。第二個輸入中的不匹配行是 ,返回爲空值。如果在參數 列中不存在連接謂詞,則每行都是匹配的行。

記住這一點,join是由限制u.id = r.userid。所以,如果where限制不存在,結果將是所有usersu.id, u.fullname, r.*

因爲有一個where條款,某些行可能會ouside的說,如果你不希望出現這種情況,使用此查詢:

select 
u.id, u.fullname, 
r.* 
from 
users as u 
left outer join 
rapports as r 
on 
u.id = r.userid and u.active = 1 
where 
and (r.closed = 0 or CONVERT(varchar, r.periodstart, 112) = convert(varchar, GETDATE(), 112)) 
order by 
u.fullname 
+0

沒有解決問題,它仍然只顯示在右表中找到匹配記錄的記錄。 – Behrens

+0

檢查我的修訂答案並閱讀全部內容。如果我錯過了一些東西告訴我,但是你的問題應該在哪裏,或者你忘了在代碼中放置左邊而不是右邊! –

+1

如果你在'WHERE'子句中提到了'u'和'r' ,你可以將'left outer'改成'inner'。 –

-1
SELECT * 
FROM #temp_table_name 

SELECT DISTINCT 
     b.NAME , 
     q.valueI 
FROM #temp_table_name q 
     RIGHT OUTER JOIN (SELECT NAME 
          FROM  (SELECT NAME , 
               valueI 
             FROM  #temp_table_name 
             INTERSECT 
             SELECT NAME , 
               valueI 
             FROM  #temp_table_name 
            ) a 
          GROUP BY a.name 
          HAVING COUNT(*) = 1 
         ) b ON q.NAME = b.NAME