Официальный сайт студ.городка НГТУ
Программирование и БД » [postgreSQL] левостороннее соединение 

#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

#2  20.12.10 11:48

Re: [postgreSQL] левостороннее соединение

наверное так:

Код::

select * from a,b where a.pole=b.pole

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

#5  20.12.10 17:10

Re: [postgreSQL] левостороннее соединение

Jaguar, преподаватель требует.

Offline

#6  20.12.10 17:27

Re: [postgreSQL] левостороннее соединение

как-то так

Код::

select a.pole1, a.pole2, (select b.col3 from b where b.pole=a.pole) as col3 from a

ну, и на каждое дополнительное поле из b надо писать вложенный запрос

Offline

#7  20.12.10 17:55

Re: [postgreSQL] левостороннее соединение

А a.pole1, a.pole2 я так понимаю это оставшиеся столбцы в первой таблице,
и не понятно что такое col3.
можно для тугодума объяснить на примере таблиц из поста №3 что есть что? (A.pole = B.pole в нем являются A.town = B.town)

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

Re: [postgreSQL] левостороннее соединение

да я ее понимаю. про уникальность тоже понятно. в запросах не силен, вот и попросил помощи.

Offline

#12  20.12.10 23:20

Re: [postgreSQL] левостороннее соединение

Flinn, ну, запрос мы тебе вместе написали... только вот за результат я не ручаюсь... реально у тебя связь между таблицами что-то типа "многие ко многим" и для уточнения нужна дополнительная связующая таблица... либо делать связь другого плана... либо запрашиваемый запрос должен выдавать не то, что реально должно выдавать левое соединение...

Offline

#13  20.12.10 23:27

Re: [postgreSQL] левостороннее соединение

Jaguar написал(а):

либо запрашиваемый запрос должен выдавать не то, что реально должно выдавать левое соединение...

Ну вот он и не выдает:))
Думаю на этом и остановлюсь.

Offline

#14  20.12.10 23:54

Re: [postgreSQL] левостороннее соединение

а если так:

select * 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)

,null нужно поторить столько раз, сколько в таблице b колонок

Offline

#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

#16  21.12.10 00:39

Re: [postgreSQL] левостороннее соединение

Matrim, браво!! спасибо огромное!!!!!!!

Offline

Программирование и БД » [postgreSQL] левостороннее соединение 

ФутЕр:)

© Hostel Web Group, 2002-2026.   Сообщить об ошибке

Сгенерировано за 0.032 сек.
Выполнено 14 запросов.