8

最近、LEFT JOINのON句に(1 = 1)などの値が含まれている可能性があることを発見しました。

これは、結合がどのように機能するかについての私の認識を壊すので、私には腹を立てます。

次の状況のより複雑なバージョンに遭遇しました。

SELECT DISTINCT Person.ID, ...
FROM Person LEFT JOIN Manager 
ON (Manager.ID = Person.ID OR Manager.ID = -1))
WHERE (...)

それは完全に合法です。「Manager.ID=-1」は、もしあれば、何を達成しますか?これは参加にどのように影響しますか?

4

3 に答える 3

7

person テーブルの場合:

id  name

1   Person One
2   Person Two
3   Person Three
4   Person Four
5   Person Five

マネージャーテーブルの場合

id  name
-1  Admin
2   Manager One
3   Manager Two

クエリが次の場合:

SELECT DISTINCT *
FROM Person LEFT JOIN Manager 
ON (Manager.id = Person.id OR Manager.id = -1)

結果は次のとおりです。

Person One  -1  Admin
Person Two  -1  Admin
Person Two  2   Manager One
Person Three    -1  Admin
Person Three    3   Manager Two
Person Four -1  Admin
Person Five -1  Admin

ここでは、すべての person 行が -1 Admin (manager テーブル) で結合され、同じ ID が manager テーブルに存在する場合は、もう 1 つの結合が発生します。

于 2009-10-07T23:34:49.930 に答える
5

IDが-1に等しいManagerテーブルの行がない限り、何も実行されません。そのような行がある場合、その行は常に個人テーブルのすべての行に結合されます。したがって、Person行ごとに、クエリ出力で2つのrosを取得する可能性があります。1つはmanager.id =を人のIDに、もう1つはManager.ID=-1行になります。

于 2009-10-07T23:24:24.230 に答える
5

また、レコードをさらにフィルタリングするために使用される AND 句も表示されます。これらのフィルタリング アクションを where 句に追加すると、結合が左結合から内部結合に変わるため、これは外部結合を扱う上で非常に重要です (where t.idfield が null のようなものでない限り)。

以下に、これがどのように機能するか、およびフィルタリング句を適切な場所に配置することが重要である理由を示します。

create table #test ( test1id int, test varchar (10)) create table #test2 ( test2id int, test1id int, test2 varchar (10))

insert into #test (test1id, test)
select 1, 'Judy'
union all
select 2, 'Sam'
union all 
select 3, 'Nathan'

insert into #test2 (test2id, test1id, test2)
select 1,1,'hello'
union all 
select 2,1,'goodbye'
union all 
select 3,2,'hello'

select * from #test t
left join #test2 t2 on t.test1id = t2.test1id
where test2 = 'goodbye'
--result set
--test1id   test    test2id test1id test2
--1 Judy    2   1   goodbye

select * from #test t
left join #test2 t2 on t.test1id = t2.test1id
and test2 = 'goodbye'
--result set 
--test1id   test    test2id test1id test2
--1 Judy    2   1   goodbye
--2 Sam NULL    NULL    NULL
--3 Nathan  NULL    NULL    NULL

where some field is null (null にならないフィールドを選択すると仮定) を使用して、次のように最初のテーブルではなく 2 番目のテーブルのレコードを取得できます。

select * from #test t
left join #test2 t2 on t.test1id = t2.test1id
where test2id is null
--result set 
--test1id   test    test2id test1id test2
--3 Nathan  NULL    NULL    NULL
于 2009-10-08T17:29:46.890 に答える