#1 20.12.10 00:01
[postgreSQL] левостороннее соединение
помогите составить запрос, который выполнял бы то же самое что и:
SELECT * FROM A LEFT OUTER JOIN B ON A.pole = B.pole
не используя left join
никак не могу справиться.
была идея сделать так:
SELECT * FROM A where (pole in (select pole from B) or not (pole in (select pole from B))
но результат не похож.
Offline
#3 20.12.10 15:45
Re: [postgreSQL] левостороннее соединение
такой тоже был вариант, делает почти так же за исключением того, что если в первой таблице нет соответствия во второй то этот запрос не обрабатывает эту ситуацию, а LEFT JOIN ставит в соответствия нули, то есть:
SELECT * FROM A LEFT OUTER JOIN B ON A.pole = B.pole дает такой результат:
n_post name reiting town n_izd name town
S3 Black 30 Paris J1 Hard_drive Paris
S6 Kovalenko 5 Moshkovo NULL NULL NULL
S7 Pereverzev 5 Leninogorsk NULL NULL NULL
S1 Smith 50 London J7 Lenta London
S1 Smith 50 London J5 Floppy_disk London
S4 Klark 50 London J7 Lenta London
S4 Klark 50 London J5 Floppy_disk London
S8 Alex 598 Orlando NULL NULL NULL
S5 Adams 30 Afine J4 Printer Afine
S5 Adams 30 Afine J3 Schityvatel Afine
S2 Jons 1210 Paris J1 Hard_drive Paris
а select * from a,b where a.pole=b.pole такой:
n_post name reiting town n_izd name town
S2 Jons 1210 Paris J1 Hard_drive Paris
S3 Black 30 Paris J1 Hard_drive Paris
S5 Adams 30 Afine J3 Schityvatel Afine
S5 Adams 30 Afine J4 Printer Afine
S4 Klark 50 London J5 Floppy_disk London
S1 Smith 50 London J5 Floppy_disk London
S4 Klark 50 London J7 Lenta London
S1 Smith 50 London J7 Lenta London
Offline
#4 20.12.10 16:54
Re: [postgreSQL] левостороннее соединение
Flinn написал(а):
за исключением того, что если в первой таблице нет соответствия во второй то этот запрос не обрабатывает эту ситуацию
да! точно... забыл это учесть... то, что я привел, это замена inner join (пордон... If more than one element is specified in the FROM list, they are cross-joined together. т.е. это все же cross-join)... щас подумаю, как это можно представить без соединений... а можно объяснить зачем такой изврат?
Исправлено Jaguar (20.12.10 17:15)
Offline
#8 20.12.10 19:04
Re: [postgreSQL] левостороннее соединение
Flinn написал(а):
А a.pole1, a.pole2 я так понимаю это оставшиеся столбцы в первой таблице
это необходимые столцы из "левой" таблицы... в твоем случае, я так понимаю, это должны быть столбцы n_post, name, reiting, town
Flinn написал(а):
и не понятно что такое col3.
это необходимые столбцы из присоединяемой таблицы... в твоем случае это n_izd,name
Flinn написал(а):
можно для тугодума объяснить на примере таблиц из поста №3 что есть что?
т.е. выборка примерно такая:
Код::
select a.n_post, a.name, a.reiting, a.town, (select b.n_izd from b where b.town=a.town) as n_izd, (select b.name from b where b.town=a.town) as bname, from a
Исправлено Jaguar (20.12.10 19:08)
Offline
#9 20.12.10 20:20
Re: [postgreSQL] левостороннее соединение
Jaguar, покорнейше благодарю.
окончательный вариант:
select A.n_post, A.name, A.reiting, A.town,
(select B.n_izd from B where B.town = A.town limit 1) as n_izd,
(select B.name from B where B.town = A.town limit 1) as name,
(select B.town from B where B.town = A.town limit 1) as town from A
так как без лимита выдает ошибку мол селект выдает больше одной строки, но с лимитом 1 обрабатывается не весь список. постараюсь сам избавиться от него.
Offline
#10 20.12.10 23:04
Re: [postgreSQL] левостороннее соединение
Flinn написал(а):
так как без лимита выдает ошибку мол селект выдает больше одной строки, но с лимитом 1 обрабатывается не весь список. постараюсь сам избавиться от него.
ну, дык, поле, по-которому ты пытаешься соединить две таблицы не является уникальным... вот ты и нарываешься на такие последствия... тебе бы на самом деле нарисовать структуру БД со связями между сущностями, чтобы ты понимал что и как ты хранишь...
Offline
#11 20.12.10 23:16
#12 20.12.10 23:20
Re: [postgreSQL] левостороннее соединение
Flinn, ну, запрос мы тебе вместе написали... только вот за результат я не ручаюсь... реально у тебя связь между таблицами что-то типа "многие ко многим" и для уточнения нужна дополнительная связующая таблица... либо делать связь другого плана... либо запрашиваемый запрос должен выдавать не то, что реально должно выдавать левое соединение...
Offline
#13 20.12.10 23:27
#14 20.12.10 23:54
#15 21.12.10 00:18
Re: [postgreSQL] левостороннее соединение
Код::
create table a (pole serial, name text default md5(random()::text));
create table b (pole serial, name text default md5(random()::text));
insert into a default values; -- 10 раз
insert into b default values; -- 11 раз
delete from b where pole in (2,7,9);
test=# select * from a;
pole | name
------+----------------------------------
1 | a3b63aa85129d2168a0436405d751a6f
2 | e32a505d8b6d768332fe18382b36724d
3 | cfb757bba866f95f88aa1a57284bc8ae
4 | d6d66644eaed100635f1ed24ccbc8f51
5 | e9fae3cc5eda4b57ace100574aaa5152
6 | 22eefe19628320bebd733e63d8021cff
7 | 960c7c1502b78d125b3d2ca4640be3d9
8 | d0d0d5c02917ee438d58da7103173713
9 | 740740a2e548916de43bde039aca8747
10 | 303cb2eac5ce06997d8d25829defeb82
(10 rows)
test=# select * from b;
pole | name
------+----------------------------------
1 | 5c0b661c3ca9c7e494bd6972b56b9407
3 | 714705ef3c5e6cb7bbe09266484f595b
4 | d82ff4e99535176e0c7fe6afc449ae85
5 | 1c3d311f6911b616745e5bc72b806e18
6 | a80358a69c8b3787a765d0723b7a0461
8 | bac566c0cc233b6c7eb6fc1934da39c7
10 | eee29853c5ab35b76984ff6a3755399f
11 | 4bffa48b23c7d5823287dd6951e5a5d2
(8 rows)
test=# select * from a,b where a.pole = b.pole union select a.*,null,null from a where a.pole not in (select a.pole from a,b where a.pole = b.pole)
pole | name | pole | name
------+----------------------------------+------+----------------------------------
4 | d6d66644eaed100635f1ed24ccbc8f51 | 4 | d82ff4e99535176e0c7fe6afc449ae85
9 | 740740a2e548916de43bde039aca8747 | |
2 | e32a505d8b6d768332fe18382b36724d | |
5 | e9fae3cc5eda4b57ace100574aaa5152 | 5 | 1c3d311f6911b616745e5bc72b806e18
3 | cfb757bba866f95f88aa1a57284bc8ae | 3 | 714705ef3c5e6cb7bbe09266484f595b
10 | 303cb2eac5ce06997d8d25829defeb82 | 10 | eee29853c5ab35b76984ff6a3755399f
7 | 960c7c1502b78d125b3d2ca4640be3d9 | |
1 | a3b63aa85129d2168a0436405d751a6f | 1 | 5c0b661c3ca9c7e494bd6972b56b9407
6 | 22eefe19628320bebd733e63d8021cff | 6 | a80358a69c8b3787a765d0723b7a0461
8 | d0d0d5c02917ee438d58da7103173713 | 8 | bac566c0cc233b6c7eb6fc1934da39c7
(10 rows)
test=# explain analyze select * from a,b where a.pole = b.pole union select a.*,null,null from a where a.pole not in (select a.pole from a,b where a.pole = b.pole)
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------
HashAggregate (cost=6.20..6.33 rows=13 width=58) (actual time=1.062..1.094 rows=10 loops=1)
-> Append (cost=1.18..6.07 rows=13 width=58) (actual time=0.319..0.943 rows=10 loops=1)
-> Hash Join (cost=1.18..2.40 rows=8 width=72) (actual time=0.285..0.385 rows=7 loops=1)
Hash Cond: (public.a.pole = public.b.pole)
-> Seq Scan on a (cost=0.00..1.10 rows=10 width=36) (actual time=0.032..0.062 rows=10 loops=1)
-> Hash (cost=1.08..1.08 rows=8 width=36) (actual time=0.132..0.132 rows=8 loops=1)
-> Seq Scan on b (cost=0.00..1.08 rows=8 width=36) (actual time=0.020..0.058 rows=8 loops=1)
-> Subquery Scan "*SELECT* 2" (cost=2.42..3.59 rows=5 width=36) (actual time=0.428..0.477 rows=3 loops=1)
-> Seq Scan on a (cost=2.42..3.54 rows=5 width=36) (actual time=0.419..0.454 rows=3 loops=1)
Filter: (NOT (hashed SubPlan 1))
SubPlan 1
-> Hash Join (cost=1.18..2.40 rows=8 width=4) (actual time=0.170..0.256 rows=7 loops=1)
Hash Cond: (public.a.pole = public.b.pole)
-> Seq Scan on a (cost=0.00..1.10 rows=10 width=4) (actual time=0.012..0.037 rows=10 loops=1)
-> Hash (cost=1.08..1.08 rows=8 width=4) (actual time=0.091..0.091 rows=8 loops=1)
-> Seq Scan on b (cost=0.00..1.08 rows=8 width=4) (actual time=0.016..0.046 rows=8 loops=1)
Total runtime: 2.031 ms
(17 rows)
test=# select * from (select a.*,b.name as "b.name" from a,b where a.pole = b.pole union select a.*,null from a where a.pole not in (select a.pole from a,b where a.pole = b.pole)) sub order by pole;
pole | name | b.name
------+----------------------------------+----------------------------------
1 | a3b63aa85129d2168a0436405d751a6f | 5c0b661c3ca9c7e494bd6972b56b9407
2 | e32a505d8b6d768332fe18382b36724d |
3 | cfb757bba866f95f88aa1a57284bc8ae | 714705ef3c5e6cb7bbe09266484f595b
4 | d6d66644eaed100635f1ed24ccbc8f51 | d82ff4e99535176e0c7fe6afc449ae85
5 | e9fae3cc5eda4b57ace100574aaa5152 | 1c3d311f6911b616745e5bc72b806e18
6 | 22eefe19628320bebd733e63d8021cff | a80358a69c8b3787a765d0723b7a0461
7 | 960c7c1502b78d125b3d2ca4640be3d9 |
8 | d0d0d5c02917ee438d58da7103173713 | bac566c0cc233b6c7eb6fc1934da39c7
9 | 740740a2e548916de43bde039aca8747 |
10 | 303cb2eac5ce06997d8d25829defeb82 | eee29853c5ab35b76984ff6a3755399f
(10 rows)Offline

