powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Авто-заполнение таблицы из исходных двух.
13 сообщений из 13, страница 1 из 1
Авто-заполнение таблицы из исходных двух.
    #38612717
Alex_Wong
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.

Есть две исходные таблицы a и b.
Каждой записи из табл. a соответствуют все записи табл. b .
Третья таблица c должна 'автоматом' заполнятся записями по факту инсерта или в a , или в b .

Правило заполнения отразил в рисунке :
(таблица с заполняется данными из a и b, и имеет поле c1, которое default = false)



Код: 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.
33.
34.
	

     a 						
	a_id	      a1	 a2				
        ----------------------------
	1	01-01-2001	xxx				
	2	02-02-2002	yyy				
	3	03-03-1999	zzz				
	4	05-05-1988	sss				
							
							

     b 						
	b_id	  b1					
	-------------
        1  	op_1					
	2	op_2					
							
							


     c 						
	c_id	a_id	     a1	         a2   b_id	  b1      c1
        ---------------------------------------------------------------
	1	1	01-01-2001	xxx	 1	op_1	  false
	2	1	01-01-2001	xxx	 2	op_2	  false
	3	2	02-02-2002	yyy	 1	op_1	  false
	4	2	02-02-2002	yyy      2	op_2	  false
	5	3	03-03-1999	zzz	 1	op_1	  false
	6	3	03-03-1999	zzz	 2	op_2	  false
	7	4	05-05-1988	sss	 1	op_1	  false
	8	4	05-05-1988	sss	 2	op_2	  false
							
							



Как ни расставлял FK, и не 'крутил' с джоинами - ничего не получилось.
Вносил в табл.b fk a_id
Ну и с инсертом в функции триггера так-же не сраслось.

Почистил исходники, может кто поможет :


Код: sql
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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
 -- DROP TABLE a;
CREATE TABLE a ( 
   a_id serial NOT NULL,
   a1 date NOT NULL DEFAULT '2001-01-01'::date,
   a2 character varying(55) NOT NULL, 
CONSTRAINT a_pkey PRIMARY KEY (a_id),
CONSTRAINT a_a1a2_key UNIQUE (a1,a2)
)


 -- DROP TABLE b;
CREATE TABLE b ( 
   b_id serial NOT NULL,
   b1 character varying(22) NOT NULL, 
CONSTRAINT b_pkey PRIMARY KEY (b_id),
CONSTRAINT b_b1_key UNIQUE (b1)
)


 -- DROP TABLE c;
CREATE TABLE c ( 
   c_id serial NOT NULL,
   a_id integer NOT NULL references a(a_id),
   a1 date NOT NULL,
   a2 character varying(55) NOT NULL, 
   b_id integer NOT NULL references b(b_id),
   b1 character varying(22) NOT NULL references b(b1), 
   c1 boolean DEFAULT false,
CONSTRAINT c_pkey PRIMARY KEY (c_id)
)



 -- DROP TRIGGER trg_sss ON a;
 -- DROP TRIGGER trg_sss ON b;
 -- DROP FUNCTION add_to_c();


CREATE OR REPLACE FUNCTION add_to_c()
  RETURNS trigger AS
$BODY$
DECLARE
    v1 integer;
    v2 date;
    v3 varchar(55);
BEGIN
IF TG_TABLE_NAME ='a' THEN
        v1 = NEW.a_id;
        v2 = NEW.a1;
        v3 = NEW.a2;
        INSERT INTO c() values (...);
        RETURN NEW;
END IF;

IF TG_TABLE_NAME ='b' THEN
        v1 = NEW.b_id;
        v3 = NEW.b1;
        INSERT INTO c(...) values (...);
        RETURN NEW;
END IF;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION add_to_c()
  OWNER TO wong;

 --

CREATE TRIGGER trg_sss
  AFTER INSERT
  ON a
  FOR EACH ROW
  EXECUTE PROCEDURE add_to_c();

CREATE TRIGGER trg_sss
  AFTER INSERT
  ON b
  FOR EACH ROW
  EXECUTE PROCEDURE add_to_c();




Как правильно делать ?
Чтобы и работало быстро, и на грабли потом не встать.
Спасибо.
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38612746
Alex_Wong
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex_Wong,

Поправил, убрал лишний references :

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
 -- DROP TABLE c;
CREATE TABLE c ( 
   c_id serial NOT NULL,
   a_id integer NOT NULL references a(a_id),
   a1 date NOT NULL,
   a2 character varying(55) NOT NULL, 
   b_id integer NOT NULL references b(b_id),
   b1 character varying(22) NOT NULL, 
   c1 boolean DEFAULT false,
CONSTRAINT c_pkey PRIMARY KEY (c_id)
)



В первой таблице a уникальным является значение двух полей
UNIQUE (a1,a2).
Это так мне надо для реальной задачи, которую упростил для примера,
надеюсь нигде больше не 'накосячил'.
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38612822
Alex_Wong<>
Третья таблица c должна 'автоматом' заполнятся записями по факту инсерта или в a , или в b .
<>
гм.
обычное декартово произведение не устроит дона ?
зачем дону третья та,бла?
он собрался её индексировать по всем перестановкам полей ? :0)
боюсь, обрезания декарта (полного произведения) условиями на основной массе выборок будут много быстрее такого недоразумения.
и всяко - удобнее
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38613089
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_WongТретья таблица c должна 'автоматом' заполнятся записями по факту инсерта или в a , или в b .при изменении или удалении строк в таблицах a или b должно ли автоматически меняться содержимое таблицы c?
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38613113
Alex_Wong
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LeXa NalBat,

вот, например, табл. a -- это список персонала;
уникальность по двум полям в ней -- чтобы хранить двух разных людей с одинаковыми фио;
(исключаю случай, что попадутся для учета два разных человека с одинаковым фио и датой рождения)

табл. b -- это список операций;

в табл. с есть поле с1 (true/false) -- это раздача прав на операцию;

вот на таком примере пытаюсь научиться и освоить 'материал'...

По Вашему вопросу, - сам толком не знаю, у меня и с простым вариантом не клеится. Но для кругозора
было бы интересно знать и структуру поддержки 'изменений'

спасибо за участие.
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38613120
Alex_Wong
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LeXa NalBat,

'автоматически меняться содержимое таблицы c'

возможно поможет on update cascade при соответствующей расстановке references;
По смежной теме была от вас подсказка, что-то буду моделировать, когда с простым случаем разберусь.
Интересует так-же хронология событий : 'чел' получил true на операцию (кто дал и когда) / потом получил false (кто дал и когда).
Пока пытаюсь понять - увязать ...
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38613132
Alex_Wong
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
йокарный бабай,

Код: sql
1.
SELECT * FROM a CROSS JOIN b order by a_id;



Как без табл. с прикрутить поле с1 для каждой записи такого 'произведения' ,
чтобы потом с ним работать ?
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38613201
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_Wong'чел' получил true на операцию (кто дал и когда) / потом получил false (кто дал и когда)вам не нужна таблица с полным декартовым произведением и дефолтом false. наоборот, в таблице C храним только разрешенные комбинации (a_id, b_id). поле c1 отсутствует, строки добавляются "вручную", и удаляются тоже (равносильно операциям "получил true", "получил false"). логирование изменений (кто и когда) можно сделать триггером - на каждое действие добавляется строка в специальную лог-таблицу. логирования изменений данных в таблице тригером , и далее по ссылкам...
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38614175
Alex_Wong
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LeXa NalBat,

да, спасибо, то что нужно.

В своем варианте предполагал на клиенте в браузере показывать состояния прав
по операциям для персонала. Поэтому и задумал 'такую' таблицу с ,
из которой мне было бы легко это вынимать.

По предложенному Вами, у меня как-раз криво получается с таким запросом:

- исходники;


Код: sql
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.
33.
34.
35.
36.
37.
 -- DROP TABLE a;
CREATE TABLE a ( 
   a_id serial NOT NULL,
   a1 date NOT NULL DEFAULT '2001-01-01'::date,
   a2 character varying(55) NOT NULL, 
CONSTRAINT a_pkey PRIMARY KEY (a_id),
CONSTRAINT a_a1a2_key UNIQUE (a1,a2)
);

 -- DROP TABLE b;
CREATE TABLE b ( 
   b_id serial NOT NULL,
   b1 character varying(22) NOT NULL, 
CONSTRAINT b_pkey PRIMARY KEY (b_id),
CONSTRAINT b_b1_key UNIQUE (b1)
);

 -- DROP TABLE c;
CREATE TABLE c ( 
   c_id serial NOT NULL,
   a_id integer NOT NULL,
   b_id integer NOT NULL,
CONSTRAINT c_pkey PRIMARY KEY (c_id)
);


-- заполняю табл. a и b :
INSERT INTO a (a1, a2) values ('1988-01-01', 'xxx');
INSERT INTO a (a1, a2) values ('1989-02-02', 'yyy');
INSERT INTO a (a1, a2) values ('1990-03-03', 'zzz');
INSERT INTO a (a1, a2) values ('1991-04-04', 'sss');
-- 
INSERT INTO b (b1) values ('op_1');
INSERT INTO b (b1) values ('op_2');
INSERT INTO b (b1) values ('op_3');
INSERT INTO b (b1) values ('op_4');
INSERT INTO b (b1) values ('op_5');





- добавление "вручную" строк в табл. c;


Код: sql
1.
2.
INSERT INTO c (a_id, b_id) values (2, 3);
INSERT INTO c (a_id, b_id) values (4, 1);





- отображение на клиенте.


Код: sql
1.
2.
3.
SELECT a.a_id, a.a1, a.a2, b.b_id, b.b1, TRUE AS c1 FROM b INNER JOIN (a RIGHT JOIN c ON a.a_id = c.a_id) ON b.b_id = c.b_id 
UNION 
SELECT a.a_id, a.a1, a.a2, b.b_id, b.b1, FALSE AS c1 FROM b INNER JOIN (a RIGHT JOIN c ON a.a_id <> c.a_id) ON b.b_id <> c.b_id order by a_id;





Тогда для отображения 'состояния дел' по конкретному 'челу', например yyy , получаю :

Код: sql
1.
2.
3.
SELECT a.a_id, a.a1, a.a2, b.b_id, b.b1, TRUE AS c1 FROM b INNER JOIN (a RIGHT JOIN c ON a.a_id = c.a_id) ON b.b_id = c.b_id Where a.a2 = 'yyy'
UNION 
SELECT a.a_id, a.a1, a.a2, b.b_id, b.b1, FALSE AS c1 FROM b INNER JOIN (a RIGHT JOIN c ON a.a_id <> c.a_id) ON b.b_id <> c.b_id Where a.a2 = 'yyy' order by a_id;



Код: plaintext
1.
2.
3.
4.
5.
6.
2;  "1989-02-02";  "yyy";  2;  "op_2";  f
2;  "1989-02-02";  "yyy";  3;  "op_3";  f
2;  "1989-02-02";  "yyy";  3;  "op_3";  t
2;  "1989-02-02";  "yyy";  4;  "op_4";  f
2;  "1989-02-02";  "yyy";  5;  "op_5";  f


Здесь видно, что хоть и правильно показало допуск на op_3 , но запрос составлен не верно, т.к. не перебирает правильно комбинации -- нет [yyy -> op_1] = f ...
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38614610
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
select * from a cross join b natural left join c;


7.2.1.1. Joined Tables
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38614681
Alex_Wong
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LeXa NalBat,

круто, спасибо.

Тогда мой вариант отображения прав по клиенту :

Код: sql
1.
2.
3.
4.
5.
6.
7.
select *, 
          case when c_id >0 then true 
          else false 
          end as c1    
from a cross join b natural left join c 
where a.a2 ='yyy'
order by b.b_id;
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38614793
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_Wong,

да, и можно сократить: c_id is not null as c1
...
Рейтинг: 0 / 0
Авто-заполнение таблицы из исходных двух.
    #38614834
Alex_Wong
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LeXa NalBat,

да, понравилось, thanks
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Авто-заполнение таблицы из исходных двух.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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