Решение с одной ссылкой на table2:
select t1.stuff
, max(case when t1.sender_id = t2.id then t2.name end) as sender_name
, max(case when t1.recipient_id = t2.id then t2.name end) as recipint_name
from t1
join t2
on t2.id in (t1.sender_id, t1.recipient_id)
group by t1.stuff;
Это немного грязный, но бывают ситуации, когда это будет удобно ,
я создал таблицы и засунул их с 10000 строк каждый (DB2 Express-C, 10,5 FixPak 1):
db2 "create table t1 (stuff int not null primary key, sender_id int not null, recipient_id int not null)"
db2 "create table t2 (id int not null primary key, name varchar(10) not null);
db2 "insert into t1 with t (n) as (values 0 union all select n+1 from t where n+1 < 10000) select n, 2*n, 2*n+1 from t"
db2 "insert into t2 with t (n) as (values 0 union all select n+1 from t where n+1 < 10000) select 2*n, 'C' || rtrim(cast(2*n as char(10))) from t"
db2 runstats on table t1 with distribution and sampled detailed indexes all
db2 runstats on table t2 with distribution and sampled detailed indexes all
и проверил план для различных запросов. Я добавил, где положение
Два суб-выбирает:
db2 "explain plan for SELECT stuff , (SELECT name FROM t2 WHERE id = sender_id) AS sender_name, (SELECT name FROM t2 WHERE id = recipient_id) AS recipient_name FROM t1 where t1.id between 500 and 600"
db2exfmt -d sample -g -1 -o sub.exfmt
Два присоединяется:
db2 "explain plan for SELECT t1.stuff, tA.name as sender_name, tB.name as recipient_name from t1 join t2 as tA on t1.sender_id = tA.id join t2 as tB on t1.sender_id = tB.id where t1.stuff between 500 and 600"
db2exfmt -d sample -g -1 -o dualjoin.exfmt
и, наконец, вариант с агрегатами и случай:
db2 "explain plan for SELECT t1.stuff, max(case when t1.sender_id = t2.id then t2.name end) as sender_name, max(case when t1.recipient_id = t2.id then t2.name end) as recipint_name from t1 join t2 on t2.id in (t1.sender_id, t1.recipient_id) group by t1.stuff"
db2exfmt -d sample -g -1 -o singlejoin.exfmt
В соответствии с этим довольно ненаучный тест, решение @Juan Carlos Oropeza является самым дешевым:
Access Plan:
-----------
Total Cost: 132.657
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
101.808
^NLJOIN
( 2)
132.657
53
/-------+--------\
101.808 1
TBSCAN FETCH
( 3) ( 7)
13.6735 13.6215
2 2
| /---+----\
101.808 1 10000
SORT IXSCAN TABLE: LELLE
( 4) ( 8) T2
13.6733 6.81423 Q1
2 1
| |
101.808 10000
FETCH INDEX: SYSIBM
( 5) SQL150906110744470
13.6625 Q1
2
/---+----\
101.808 10000
IXSCAN TABLE: LELLE
( 6) T1
6.84113 Q2
1
|
10000
INDEX: SYSIBM
SQL150906110646160
Q2
Использование двух суб-выбирает, как в @ shA.t будет немного дороже:
Access Plan:
-----------
Total Cost: 251.679
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
101.808
>^NLJOIN
( 2)
251.679
103.99
/-------+--------\
101.808 1
TBSCAN FETCH
( 3) ( 12)
132.695 13.6215
52.9898 2
| /---+----\
101.808 1 10000
SORT IXSCAN TABLE: LELLE
( 4) ( 13) T2
132.691 6.81423 Q1
52.9898 1
| |
101.808 10000
>^NLJOIN INDEX: SYSIBM
( 5) SQL150906110744470
132.67 Q1
52.9898
/-------+--------\
101.808 1
TBSCAN FETCH
( 6) ( 10)
13.6881 13.6215
2 2
| /---+----\
101.808 1 10000
SORT IXSCAN TABLE: LELLE
( 7) ( 11) T2
13.6839 6.81423 Q2
2 1
| |
101.808 10000
FETCH INDEX: SYSIBM
( 8) SQL150906110744470
13.6625 Q2
2
/---+----\
101.808 10000
IXSCAN TABLE: LELLE
( 9) T1
6.84113 Q3
1
|
10000
INDEX: SYSIBM
SQL150906110646160
Q3
Мои решения является самым дорогим:
Access Plan:
-----------
Total Cost: 758.822
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
10000
GRPBY
( 2)
758.139
124.996
|
20000
NLJOIN
( 3)
756.923
124.996
/----------+----------\
10000 2
FETCH FETCH
( 4) ( 6)
122.351 27.0171
49 3.96667
/---+----\ /---+----\
10000 10000 2 10000
IXSCAN TABLE: LELLE RIDSCN TABLE: LELLE
( 5) T1 ( 7) T2
58.1551 Q2 13.6291 Q1
21 2
| /-------+-------\
10000 1.0016 1.0016
INDEX: SYSIBM SORT SORT
SQL150906110646160 ( 8) ( 10)
Q2 6.81465 6.81465
1 1
| |
1.0016 1.0016
IXSCAN IXSCAN
( 9) ( 11)
6.81423 6.81423
1 1
| |
10000 10000
INDEX: SYSIBM INDEX: SYSIBM
SQL150906110744470 SQL150906110744470
Q1 Q1
Для которого RDBMS это ?Пожалуйста, добавьте соответствующий тег - спасибо –
Вам нужно будет сделать два соединения, так как вы хотите получить два разных результата оттуда –