powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как можно склеить таблицы?
21 сообщений из 21, страница 1 из 1
Как можно склеить таблицы?
    #33808409
Jorje
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет! Как можно склеить таблицы ?

Т.е. есть таблицы:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
# SELECT * FROM a;
 a
----
 a1
 a2
 a3
 a4
 a5
( 5  rows)

# SELECT * FROM b;
 b
----
 b1
 b2
 b3
( 3  rows)

# SELECT * FROM c;
 c
----
 c1
( 1  row)

Хочется одним запросом получить такое:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
# SELECT ...
 a  | b  | c
----+----+----
 a1 | b1 | c1
 a2 | b2 |
 a3 | b3 |
 a4 |    |
 a5 |    |
( 5  rows)

Спасибо заранее!
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808419
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А тебе всё равно, как строки из одной таблицы будут соотносится со строками из другой?
Или есть притензии по этому поводу?

-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808449
Jorje
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вообще, важно, да. Т.е. результат должен быть именно таким, как в примере.
Но с удовольствием бы посмотрел, как сделать и без этого условия. Пока я вообще не знаю, с какой стороны подойти к этому запросу :(

для удобства:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
CREATE TABLE A (
    a varchar( 5 )
);

INSERT INTO A VALUES ('a1');
INSERT INTO A VALUES ('a2');
INSERT INTO A VALUES ('a3');
INSERT INTO A VALUES ('a4');
INSERT INTO A VALUES ('a5');

CREATE TABLE B (
    b varchar( 5 )
);

INSERT INTO B VALUES ('b1');
INSERT INTO B VALUES ('b2');
INSERT INTO B VALUES ('b3');

CREATE TABLE C (
    c varchar( 5 )
);

INSERT INTO C VALUES ('c1');
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808462
Фотография pamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кажется я начинаю догадываться, что соединение идет по индексам в значении колонки (цифрам). Но вот почему бы автору прямо об этом не сказать?
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808483
Jorje
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
:)

Это пример такой, значения полей могут быть произвольными
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808486
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вариант (на твоих тестовых данных):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
select a, b, c
  from (
          select a,
                 (select count( 1 ) from a aa where aa.a <= a.a) as rn_a
            from a
       ) v_a
  full outer join
       (
          select b,
                 (select count( 1 ) from b bb where bb.b <= b.b) as rn_b
            from b
       ) v_b
    on rn_a = rn_b
  full outer join
       (
          select c,
                 (select count( 1 ) from c cc where cc.c <= c.c) as rn_c
            from c
       ) v_c
    on rn_b = rn_c  
order by a,b,c

Query finished, retrieving results...

A    B    C
--   --   --
a1   b1   c1
a2   b2
a3   b3
a4
a5

 5  row(s) retrieved


-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808514
Jorje
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владимор, ты волшебник!? Работает! Спасибо! Буду теперь понимать :)
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808562
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JorjeВладимор, ты волшебник!? Работает! Спасибо! Буду теперь понимать :)
Я не волшебник, я только учусь (с) :)
А про понимание - там такая логика заложена:
У нас в таблицах нет явно заданного поля, по которому можно было бы их соеденить.
Поэтому создадим это поле на момент выполнения запроса (это подзапросы для получения значений A_RN, B_RN, C_RN).
Далее объеденим таблицы по этому полю.
Кстати, в этом подходе есть скрытый камень, который можно обойти лишь в том случае, если в каждой из таблиц есть уникальное сочетание полей.

Что бы увидеть эту граблю, попробуй добавить, к примеру, в таблицу "А" еще одно значение "A1" :)
Ну как? Правда, результат немного не тот, что ты ожидал?!

-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808575
Jorje
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати, чтобы работало на любых данных, видимо, нужно селекты, типа:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
# select a, (select count( 1 ) from a aa where aa.a <= a.a) as rn_a from a;
 a  | rn_a
----+------
 a1 |     1 
 a2 |     2 
 a3 |     3 
 a4 |     4 
 a5 |     5 
( 5  rows)

заменить на:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
# select a, (select count( 1 ) from a aa where aa.oid <= a.oid) as rn_a from a;
 a  | rn_a
----+------
 a1 |     1 
 a2 |     2 
 a3 |     3 
 a4 |     4 
 a5 |     5 
( 5  rows)

Или я не прав ?
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808590
ZemA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Владимор
outer можно не писать :)

А вообще классный скрипт. К тому же в нем есть ответ на вопрос "как пронумеровать строки?"
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808599
Jorje
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, вроде, нужно использовать oid и убрать в конце group by.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
select a, b, c
  from (
          select a,
                 (select count( 1 ) from a aa where aa.oid <= a.oid) as rn_a
            from a
       ) v_a
  full outer join
       (
          select b,
                 (select count( 1 ) from b bb where bb.oid <= b.oid) as rn_b
            from b
       ) v_b
    on rn_a = rn_b
  full outer join
       (
          select c,
                 (select count( 1 ) from c cc where cc.oid <= c.oid) as rn_c
            from c
       ) v_c
    on rn_b = rn_c  
;

 a  | b  | c
----+----+----
 a1 | b1 | c1
 a2 | b2 |
 a3 | b3 |
 a4 |    |
 a5 |    |
 a1 |    |
 ( 6  rows)
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808608
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JorjeКстати, чтобы работало на любых данных, видимо, нужно селекты, типа:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
# select a, (select count( 1 ) from a aa where aa.a <= a.a) as rn_a from a;
 a  | rn_a
----+------
 a1 |     1 
 a2 |     2 
 a3 |     3 
 a4 |     4 
 a5 |     5 
( 5  rows)

заменить на:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
# select a, (select count( 1 ) from a aa where aa.oid <= a.oid) as rn_a from a;
 a  | rn_a
----+------
 a1 |     1 
 a2 |     2 
 a3 |     3 
 a4 |     4 
 a5 |     5 
( 5  rows)

Или я не прав ?Все так и есть. Это как раз то, о чем я тебя предостерегал в своем предыдушем ответе
Однако, я бы таки заменил на вот такой вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
# select a, (select count( 1 ) from a aa where aa.a <= a.a and aa.oid <= a.oid) as rn_a from a;
 a  | rn_a
----+------
 a1 |     1 
 a2 |     2 
 a3 |     3 
 a4 |     4 
 a5 |     5 
( 5  rows)
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808613
ZemA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
там order by :)
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808628
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZemA> Владимор
outer можно не писать :)Эт я знаю, но пишу исключительно в эстетических целях - что бы всё было красиво ;)
ZemAА вообще классный скрипт. К тому же в нем есть ответ на вопрос "как пронумеровать строки?"А вот с этим согласен на все 100% :)


-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808651
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JorjeДа, вроде, нужно использовать oid и убрать в конце group by.
Про OID я уже отвечал - можно использовать только его, но лично мне больше по вкусу вариант с указанием и поля таблицы и OID-а.
Что касается GROUP BY - то его там нет :)
ТАм есть только ORDER BY - он добавлен опять же исключительно из эстетических соображений - что бы гарантированно обеспечить именно тот вид результата, который я желаю увидеть.
Оно ведь сервер может вернуть резульата совершенно в произвольном порядке...
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808662
ZemA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимор Конев
Однако, я бы таки заменил на вот такой вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
# select a, (select count( 1 ) from a aa where aa.a <= a.a and aa.oid <= a.oid) as rn_a from a;
 a  | rn_a
----+------
 a1 |     1 
 a2 |     2 
 a3 |     3 
 a4 |     4 
 a5 |     5 
( 5  rows)

почему? oid'ы ведь не повторяются. а если пк комтозитный (полей эдак из 4), их ведь все в where придется писать :) помоему oid'a достаточно.
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808698
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZemAпочему? oid'ы ведь не повторяются. а если пк комтозитный (полей эдак из 4), их ведь все в where придется писать :) помоему oid'a достаточно.Просто сравни результаты работы двух запросов.
Вариант с сравнением только по OID привел автор вопроса.
Заметь, насколько результат такого подхода отличается от того, что будет в случае выполнения вот такого запроса:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select a, b, c
  from (
          select a,
                 (select count( 1 ) from a aa where aa.a <= a.a and aa.oid <= a.oid) as rn_a
            from a
       ) v_a
  full outer join
       (
          select b,
                 (select count( 1 ) from b bb where bb.oid <= b.oid) as rn_b
            from b
       ) v_b
    on rn_a = rn_b
  full outer join
       (
          select c,
                 (select count( 1 ) from c cc where cc.oid <= c.oid) as rn_c
            from c
       ) v_c
    on rn_b = rn_c  
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808769
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимор КоневОднако, я бы таки заменил на вот такой вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
# select a, (select count( 1 ) from a aa where aa.a <= a.a and aa.oid <= a.oid) as rn_a from a;
 a  | rn_a
----+------
 a1 |     1 
 a2 |     2 
 a3 |     3 
 a4 |     4 
 a5 |     5 
( 5  rows)
ошибка: rn_a не уникален

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
=> create table a ( a text ) with oids;
CREATE TABLE
=> insert into a values ( 'b' );
INSERT  16953   1 
=> insert into a values ( 'a' );
INSERT  16954   1 
=> select a, (select count( 1 ) from a aa where aa.a <= a.a and aa.oid <= a.oid) as rn_a from a;
 a | rn_a
---+------
 b |     1 
 a |     1 
( 2  rows)
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808800
ZemA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
возможно имелось в виду так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
select a, b, c
  from (
          select a,
                 (select count( 1 ) from a aa where aa.a <= a.a and aa.oid <= a.oid) as rn_a
            from a
       ) v_a
  full outer join
       (
          select b,
                 (select count( 1 ) from b bb where bb.b <= b.b and bb.oid <= b.oid) as rn_b
            from b
       ) v_b
    on rn_a = rn_b
  full outer join
       (
          select c,
                 (select count( 1 ) from c cc where cc.c <= c.c and cc.oid <= c.oid) as rn_c
            from c
       ) v_c
    on rn_b = rn_c  
тогда, для
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
# select * from a;
 a
----
 a1
 a2
 a3
 a4
 a5
 a1
( 6  rows)

# select * from b;
 b
----
 b1
 b2
 b3
( 3  rows)

# select * from c;
 c
----
 c1
( 1  row)
получается
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 a  | b  | c
----+----+----
 a1 | b1 | c1
 a2 | b2 |
 a1 | b2 |
 a3 | b3 |
 a4 |    |
 a5 |    |
( 6  rows)
а для
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
select a, b, c
  from (
          select a,
                 (select count( 1 ) from a aa where aa.oid <= a.oid) as rn_a
            from a
       ) v_a
  full outer join
       (
          select b,
                 (select count( 1 ) from b bb where bb.oid <= b.oid) as rn_b
            from b
       ) v_b
    on rn_a = rn_b
  full outer join
       (
          select c,
                 (select count( 1 ) from c cc where cc.oid <= c.oid) as rn_c
            from c
       ) v_c
    on rn_b = rn_c;
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 a  | b  | c
----+----+----
 a1 | b1 | c1
 a2 | b2 |
 a3 | b3 |
 a4 |    |
 a5 |    |
 a1 |    |
( 6  rows)
второй вариант мне нравится больше
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808813
ZemA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeXa NalBat Владимор КоневОднако, я бы таки заменил на вот такой вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
# select a, (select count( 1 ) from a aa where aa.a <= a.a and aa.oid <= a.oid) as rn_a from a;
 a  | rn_a
----+------
 a1 |     1 
 a2 |     2 
 a3 |     3 
 a4 |     4 
 a5 |     5 
( 5  rows)
ошибка: rn_a не уникален

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
=> create table a ( a text ) with oids;
CREATE TABLE
=> insert into a values ( 'b' );
INSERT  16953   1 
=> insert into a values ( 'a' );
INSERT  16954   1 
=> select a, (select count( 1 ) from a aa where aa.a <= a.a and aa.oid <= a.oid) as rn_a from a;
 a | rn_a
---+------
 b |     1 
 a |     1 
( 2  rows)

это если
Код: plaintext
1.
select count( 1 ) from a aa where aa.a <= a.a and aa.oid <= a.oid
а если так
Код: plaintext
1.
select count( 1 ) from a aa where aa.oid <= a.oid
все нормально
...
Рейтинг: 0 / 0
Как можно склеить таблицы?
    #33808858
Jorje
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что-то на этих данных explain мне насчитал cost=70251.99..70719.59, а работает быстро :)
А вообще, план так и говорит: "не надо решать такие задачи таким способом, не бывает таких задач" :)
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как можно склеить таблицы?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]