Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как можно склеить таблицы? / 21 сообщений из 21, страница 1 из 1
22.06.2006, 13:00
    #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
22.06.2006, 13:02
    #33808419
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно склеить таблицы?
А тебе всё равно, как строки из одной таблицы будут соотносится со строками из другой?
Или есть притензии по этому поводу?

-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер
...
Рейтинг: 0 / 0
22.06.2006, 13:09
    #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
22.06.2006, 13:13
    #33808462
pamir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно склеить таблицы?
Кажется я начинаю догадываться, что соединение идет по индексам в значении колонки (цифрам). Но вот почему бы автору прямо об этом не сказать?
...
Рейтинг: 0 / 0
22.06.2006, 13:17
    #33808483
Jorje
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно склеить таблицы?
:)

Это пример такой, значения полей могут быть произвольными
...
Рейтинг: 0 / 0
22.06.2006, 13:17
    #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
22.06.2006, 13:24
    #33808514
Jorje
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно склеить таблицы?
Владимор, ты волшебник!? Работает! Спасибо! Буду теперь понимать :)
...
Рейтинг: 0 / 0
22.06.2006, 13:33
    #33808562
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно склеить таблицы?
JorjeВладимор, ты волшебник!? Работает! Спасибо! Буду теперь понимать :)
Я не волшебник, я только учусь (с) :)
А про понимание - там такая логика заложена:
У нас в таблицах нет явно заданного поля, по которому можно было бы их соеденить.
Поэтому создадим это поле на момент выполнения запроса (это подзапросы для получения значений A_RN, B_RN, C_RN).
Далее объеденим таблицы по этому полю.
Кстати, в этом подходе есть скрытый камень, который можно обойти лишь в том случае, если в каждой из таблиц есть уникальное сочетание полей.

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

-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер
...
Рейтинг: 0 / 0
22.06.2006, 13:35
    #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
22.06.2006, 13:37
    #33808590
ZemA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно склеить таблицы?
> Владимор
outer можно не писать :)

А вообще классный скрипт. К тому же в нем есть ответ на вопрос "как пронумеровать строки?"
...
Рейтинг: 0 / 0
22.06.2006, 13:41
    #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
22.06.2006, 13:43
    #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
22.06.2006, 13:43
    #33808613
ZemA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно склеить таблицы?
там order by :)
...
Рейтинг: 0 / 0
22.06.2006, 13:45
    #33808628
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно склеить таблицы?
ZemA> Владимор
outer можно не писать :)Эт я знаю, но пишу исключительно в эстетических целях - что бы всё было красиво ;)
ZemAА вообще классный скрипт. К тому же в нем есть ответ на вопрос "как пронумеровать строки?"А вот с этим согласен на все 100% :)


-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер
...
Рейтинг: 0 / 0
22.06.2006, 13:48
    #33808651
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно склеить таблицы?
JorjeДа, вроде, нужно использовать oid и убрать в конце group by.
Про OID я уже отвечал - можно использовать только его, но лично мне больше по вкусу вариант с указанием и поля таблицы и OID-а.
Что касается GROUP BY - то его там нет :)
ТАм есть только ORDER BY - он добавлен опять же исключительно из эстетических соображений - что бы гарантированно обеспечить именно тот вид результата, который я желаю увидеть.
Оно ведь сервер может вернуть резульата совершенно в произвольном порядке...
...
Рейтинг: 0 / 0
22.06.2006, 13:51
    #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
22.06.2006, 13:57
    #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
22.06.2006, 14:14
    #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
22.06.2006, 14:21
    #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
22.06.2006, 14:24
    #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
22.06.2006, 14:38
    #33808858
Jorje
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно склеить таблицы?
Что-то на этих данных explain мне насчитал cost=70251.99..70719.59, а работает быстро :)
А вообще, план так и говорит: "не надо решать такие задачи таким способом, не бывает таких задач" :)
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Как можно склеить таблицы? / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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