How to INSERT INTO a table (not UPDATE) on conflict, generating a new key value?

I have two Postgres tables as shown below, primary key is id:

table1:
id | name
----------
1  | Bob
3  | Steven
table2:
id | name
----------
2  | John
3  | Jack

I would like to combine these two tables by inserting table2 to table1, and table1 should look like below after the operation.
Essentially, it can maintain the same primary key if there is no conflict, but when it has conflict, it will generate a new id for the incoming data from table2, and insert that as a new row in table1. In this example, ‘Jack’ from table2 will be inserted as a new row with a new id of 4 (max id from table1 + 1).

id | name
----------
1  | Bob
2  | John
3  | Steven
4  | Jack

Below is my current approach. Which updates the id in conflicted row in table1 (not what I want):

INSERT INTO table1 (id, name)
SELECT id, name
FROM table2
ON CONFLICT(id) DO UPDATE SET id=nextval(pg_get_serial_sequence('table1', 'id'));

How to insert a new row with a new id?

2

  1. Insert non-conflicting rows:

    INSERT INTO table1 (id, name)
    SELECT id, name FROM table2
    ON CONFLICT(id) DO NOTHING;
    
  2. Insert conflicting rows with new IDs:

    INSERT INTO table1 (id, name)
    SELECT nextval(pg_get_serial_sequence('table1', 'id')), name
    FROM table2 t2
    WHERE EXISTS (SELECT 1 FROM table1 t1 WHERE t1.id = t2.id);
    ``
    

conflicting rows are inserted with a new ID.

New contributor

Krutarth is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

2

There isn’t a direct and simple way to achieve the described results. Unless there is a compelling reason to preserve non-conflicting id values from table2, the best option is insert the name values from table2 and discard the original id values.

The following establishes the demonstration environment:

CREATE TABLE table1 (id serial PRIMARY KEY, name TEXT);

CREATE TABLE table2 (id serial PRIMARY KEY, name TEXT);

INSERT INTO
  table1 (id, name)
VALUES
  (1, 'Bob'),
  (3, 'Steven');

INSERT INTO
  table2 (id, name)
VALUES
  (2, 'John'),
  (3, 'Jack');

The following demonstrates an approach that can be used to add the contents of table2 to table1 while preserving non-conflicting id values from table2:

WITH set_seq AS
  (SELECT s.dst_seq,
          SETVAL(s.dst_seq,
                 GREATEST((SELECT MAX(id) FROM table1),
                          (SELECT MAX(id) FROM table2)))
     FROM (SELECT PG_GET_SERIAL_SEQUENCE('table1', 'id') AS dst_seq) s)
INSERT INTO table1 (id, name)
SELECT CASE WHEN dst.id IS NOT NULL THEN NEXTVAL(set_seq.dst_seq) ELSE src.id END, src.name
  FROM set_seq
  CROSS JOIN table2 src
  LEFT JOIN table1 dst ON dst.id = src.id;

The first part ensures that the sequence that provides id values will not conflict with the id values of either table. After the preceding SQL runs, the contents of table1 will be:

id name
1 Bob
2 John
3 Steven
4 Jack

Assuming table1.id draws from a sequence.

Notably, the MERGE command (Postgres 15+) cannot be used (as single command), since it only allows UPDATE / DELETE (or nothing) WHEN MATCHED.

Simple case: no concurrent writes possible

First, know the name of the underlying sequence for table1.id. Same path for serial and IDENTITY columns. See:

  • Auto increment table column

If you are not sure, find out:

SELECT pg_get_serial_sequence('table1', 'id') AS seq;

See:

  • How to reset Postgres’ primary key sequence when it falls out of sync?

Proceeding with the default name public.table1_id_seq here. Replace with your actual sequence name. Schema-qualify to be safe.

If the maximum value in table2.id can be higher than the current
value of the sequence, set it to the higher value. Only write if necessary:

SELECT CASE WHEN t2_max > t1_seq THEN setval('public.table1_id_seq', t2_max) END
FROM  (SELECT max(id) AS t2_max FROM table2) t2
    , (SELECT last_value + is_called::int AS t1_seq FROM public.table1_id_seq) s;

Compare to the current value of the sequence, rather than the maximum tabl1.id. Subtle difference. We wouldn’t want to decrease the sequence value, risking possible conflicts.

Note last_value + is_called::int. Internally, every sequence has a boolean tag is_called. The default is true – same as for the 2nd parameter of the function setval(). Then the next serial number will be incremented. Cast to integer and add, true1 / false0, and everything falls into place.

Then, probably simplest and fastest:

INSERT INTO table1 (id, name)
SELECT CASE WHEN t1.id IS NULL
            THEN t2.id
            ELSE nextval('table1_id_seq') END
     , t2.name
FROM   table2 t2
LEFT   JOIN table1 t1 USING (id);

Concurrent writes possible

If there can be concurrent writes in either table, LOCK both to avoid race conditions. The appropriate lock strength should be SHARE ROW EXCLUSIVE to protect tables against concurrent data changes exclusively.

And do it all in a single transaction. (Can’t hurt either way):

BEGIN;

LOCK table1 IN SHARE ROW EXCLUSIVE MODE;  -- protect against concurrent data changes, exclusively
LOCK table2 IN SHARE ROW EXCLUSIVE MODE;

SELECT CASE WHEN t2_max > t1_seq THEN setval('public.table1_id_seq', t2_max) END
FROM  (SELECT max(id) AS t2_max FROM table2) t2
    , (SELECT last_value + is_called::int AS t1_seq FROM public.table1_id_seq) s;

INSERT INTO table1 (id, name)
SELECT CASE WHEN t1.id IS NULL
            THEN t2.id
            ELSE nextval('table1_id_seq') END
     , t2.name
FROM   table2 t2
LEFT   JOIN table1 t1 USING (id);

COMMIT;

fiddle

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

How to INSERT INTO a table (not UPDATE) on conflict, generating a new key value?

I have two Postgres tables as shown below, primary key is id:

table1:
id | name
----------
1  | Bob
3  | Steven
table2:
id | name
----------
2  | John
3  | Jack

I would like to combine these two tables by inserting table2 to table1, and table1 should look like below after the operation.
Essentially, it can maintain the same primary key if there is no conflict, but when it has conflict, it will generate a new id for the incoming data from table2, and insert that as a new row in table1. In this example, ‘Jack’ from table2 will be inserted as a new row with a new id of 4 (max id from table1 + 1).

id | name
----------
1  | Bob
2  | John
3  | Steven
4  | Jack

Below is my current approach. Which updates the id in conflicted row in table1 (not what I want):

INSERT INTO table1 (id, name)
SELECT id, name
FROM table2
ON CONFLICT(id) DO UPDATE SET id=nextval(pg_get_serial_sequence('table1', 'id'));

How to insert a new row with a new id?

2

  1. Insert non-conflicting rows:

    INSERT INTO table1 (id, name)
    SELECT id, name FROM table2
    ON CONFLICT(id) DO NOTHING;
    
  2. Insert conflicting rows with new IDs:

    INSERT INTO table1 (id, name)
    SELECT nextval(pg_get_serial_sequence('table1', 'id')), name
    FROM table2 t2
    WHERE EXISTS (SELECT 1 FROM table1 t1 WHERE t1.id = t2.id);
    ``
    

conflicting rows are inserted with a new ID.

New contributor

Krutarth is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

2

There isn’t a direct and simple way to achieve the described results. Unless there is a compelling reason to preserve non-conflicting id values from table2, the best option is insert the name values from table2 and discard the original id values.

The following establishes the demonstration environment:

CREATE TABLE table1 (id serial PRIMARY KEY, name TEXT);

CREATE TABLE table2 (id serial PRIMARY KEY, name TEXT);

INSERT INTO
  table1 (id, name)
VALUES
  (1, 'Bob'),
  (3, 'Steven');

INSERT INTO
  table2 (id, name)
VALUES
  (2, 'John'),
  (3, 'Jack');

The following demonstrates an approach that can be used to add the contents of table2 to table1 while preserving non-conflicting id values from table2:

WITH set_seq AS
  (SELECT s.dst_seq,
          SETVAL(s.dst_seq,
                 GREATEST((SELECT MAX(id) FROM table1),
                          (SELECT MAX(id) FROM table2)))
     FROM (SELECT PG_GET_SERIAL_SEQUENCE('table1', 'id') AS dst_seq) s)
INSERT INTO table1 (id, name)
SELECT CASE WHEN dst.id IS NOT NULL THEN NEXTVAL(set_seq.dst_seq) ELSE src.id END, src.name
  FROM set_seq
  CROSS JOIN table2 src
  LEFT JOIN table1 dst ON dst.id = src.id;

The first part ensures that the sequence that provides id values will not conflict with the id values of either table. After the preceding SQL runs, the contents of table1 will be:

id name
1 Bob
2 John
3 Steven
4 Jack

Assuming table1.id draws from a sequence.

Notably, the MERGE command (Postgres 15+) cannot be used (as single command), since it only allows UPDATE / DELETE (or nothing) WHEN MATCHED.

Simple case: no concurrent writes possible

First, know the name of the underlying sequence for table1.id. Same path for serial and IDENTITY columns. See:

  • Auto increment table column

If you are not sure, find out:

SELECT pg_get_serial_sequence('table1', 'id') AS seq;

See:

  • How to reset Postgres’ primary key sequence when it falls out of sync?

Proceeding with the default name public.table1_id_seq here. Replace with your actual sequence name. Schema-qualify to be safe.

If the maximum value in table2.id can be higher than the current
value of the sequence, set it to the higher value. Only write if necessary:

SELECT CASE WHEN t2_max > t1_seq THEN setval('public.table1_id_seq', t2_max) END
FROM  (SELECT max(id) AS t2_max FROM table2) t2
    , (SELECT last_value + is_called::int AS t1_seq FROM public.table1_id_seq) s;

Compare to the current value of the sequence, rather than the maximum tabl1.id. Subtle difference. We wouldn’t want to decrease the sequence value, risking possible conflicts.

Note last_value + is_called::int. Internally, every sequence has a boolean tag is_called. The default is true – same as for the 2nd parameter of the function setval(). Then the next serial number will be incremented. Cast to integer and add, true1 / false0, and everything falls into place.

Then, probably simplest and fastest:

INSERT INTO table1 (id, name)
SELECT CASE WHEN t1.id IS NULL
            THEN t2.id
            ELSE nextval('table1_id_seq') END
     , t2.name
FROM   table2 t2
LEFT   JOIN table1 t1 USING (id);

Concurrent writes possible

If there can be concurrent writes in either table, LOCK both to avoid race conditions. The appropriate lock strength should be SHARE ROW EXCLUSIVE to protect tables against concurrent data changes exclusively.

And do it all in a single transaction. (Can’t hurt either way):

BEGIN;

LOCK table1 IN SHARE ROW EXCLUSIVE MODE;  -- protect against concurrent data changes, exclusively
LOCK table2 IN SHARE ROW EXCLUSIVE MODE;

SELECT CASE WHEN t2_max > t1_seq THEN setval('public.table1_id_seq', t2_max) END
FROM  (SELECT max(id) AS t2_max FROM table2) t2
    , (SELECT last_value + is_called::int AS t1_seq FROM public.table1_id_seq) s;

INSERT INTO table1 (id, name)
SELECT CASE WHEN t1.id IS NULL
            THEN t2.id
            ELSE nextval('table1_id_seq') END
     , t2.name
FROM   table2 t2
LEFT   JOIN table1 t1 USING (id);

COMMIT;

fiddle

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

How to INSERT INTO a table (not UPDATE) on conflict, generating a new key value?

I have two Postgres tables as shown below, primary key is id:

table1:
id | name
----------
1  | Bob
3  | Steven
table2:
id | name
----------
2  | John
3  | Jack

I would like to combine these two tables by inserting table2 to table1, and table1 should look like below after the operation.
Essentially, it can maintain the same primary key if there is no conflict, but when it has conflict, it will generate a new id for the incoming data from table2, and insert that as a new row in table1. In this example, ‘Jack’ from table2 will be inserted as a new row with a new id of 4 (max id from table1 + 1).

id | name
----------
1  | Bob
2  | John
3  | Steven
4  | Jack

Below is my current approach. Which updates the id in conflicted row in table1 (not what I want):

INSERT INTO table1 (id, name)
SELECT id, name
FROM table2
ON CONFLICT(id) DO UPDATE SET id=nextval(pg_get_serial_sequence('table1', 'id'));

How to insert a new row with a new id?

2

  1. Insert non-conflicting rows:

    INSERT INTO table1 (id, name)
    SELECT id, name FROM table2
    ON CONFLICT(id) DO NOTHING;
    
  2. Insert conflicting rows with new IDs:

    INSERT INTO table1 (id, name)
    SELECT nextval(pg_get_serial_sequence('table1', 'id')), name
    FROM table2 t2
    WHERE EXISTS (SELECT 1 FROM table1 t1 WHERE t1.id = t2.id);
    ``
    

conflicting rows are inserted with a new ID.

New contributor

Krutarth is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

2

There isn’t a direct and simple way to achieve the described results. Unless there is a compelling reason to preserve non-conflicting id values from table2, the best option is insert the name values from table2 and discard the original id values.

The following establishes the demonstration environment:

CREATE TABLE table1 (id serial PRIMARY KEY, name TEXT);

CREATE TABLE table2 (id serial PRIMARY KEY, name TEXT);

INSERT INTO
  table1 (id, name)
VALUES
  (1, 'Bob'),
  (3, 'Steven');

INSERT INTO
  table2 (id, name)
VALUES
  (2, 'John'),
  (3, 'Jack');

The following demonstrates an approach that can be used to add the contents of table2 to table1 while preserving non-conflicting id values from table2:

WITH set_seq AS
  (SELECT s.dst_seq,
          SETVAL(s.dst_seq,
                 GREATEST((SELECT MAX(id) FROM table1),
                          (SELECT MAX(id) FROM table2)))
     FROM (SELECT PG_GET_SERIAL_SEQUENCE('table1', 'id') AS dst_seq) s)
INSERT INTO table1 (id, name)
SELECT CASE WHEN dst.id IS NOT NULL THEN NEXTVAL(set_seq.dst_seq) ELSE src.id END, src.name
  FROM set_seq
  CROSS JOIN table2 src
  LEFT JOIN table1 dst ON dst.id = src.id;

The first part ensures that the sequence that provides id values will not conflict with the id values of either table. After the preceding SQL runs, the contents of table1 will be:

id name
1 Bob
2 John
3 Steven
4 Jack

Assuming table1.id draws from a sequence.

Notably, the MERGE command (Postgres 15+) cannot be used (as single command), since it only allows UPDATE / DELETE (or nothing) WHEN MATCHED.

Simple case: no concurrent writes possible

First, know the name of the underlying sequence for table1.id. Same path for serial and IDENTITY columns. See:

  • Auto increment table column

If you are not sure, find out:

SELECT pg_get_serial_sequence('table1', 'id') AS seq;

See:

  • How to reset Postgres’ primary key sequence when it falls out of sync?

Proceeding with the default name public.table1_id_seq here. Replace with your actual sequence name. Schema-qualify to be safe.

If the maximum value in table2.id can be higher than the current
value of the sequence, set it to the higher value. Only write if necessary:

SELECT CASE WHEN t2_max > t1_seq THEN setval('public.table1_id_seq', t2_max) END
FROM  (SELECT max(id) AS t2_max FROM table2) t2
    , (SELECT last_value + is_called::int AS t1_seq FROM public.table1_id_seq) s;

Compare to the current value of the sequence, rather than the maximum tabl1.id. Subtle difference. We wouldn’t want to decrease the sequence value, risking possible conflicts.

Note last_value + is_called::int. Internally, every sequence has a boolean tag is_called. The default is true – same as for the 2nd parameter of the function setval(). Then the next serial number will be incremented. Cast to integer and add, true1 / false0, and everything falls into place.

Then, probably simplest and fastest:

INSERT INTO table1 (id, name)
SELECT CASE WHEN t1.id IS NULL
            THEN t2.id
            ELSE nextval('table1_id_seq') END
     , t2.name
FROM   table2 t2
LEFT   JOIN table1 t1 USING (id);

Concurrent writes possible

If there can be concurrent writes in either table, LOCK both to avoid race conditions. The appropriate lock strength should be SHARE ROW EXCLUSIVE to protect tables against concurrent data changes exclusively.

And do it all in a single transaction. (Can’t hurt either way):

BEGIN;

LOCK table1 IN SHARE ROW EXCLUSIVE MODE;  -- protect against concurrent data changes, exclusively
LOCK table2 IN SHARE ROW EXCLUSIVE MODE;

SELECT CASE WHEN t2_max > t1_seq THEN setval('public.table1_id_seq', t2_max) END
FROM  (SELECT max(id) AS t2_max FROM table2) t2
    , (SELECT last_value + is_called::int AS t1_seq FROM public.table1_id_seq) s;

INSERT INTO table1 (id, name)
SELECT CASE WHEN t1.id IS NULL
            THEN t2.id
            ELSE nextval('table1_id_seq') END
     , t2.name
FROM   table2 t2
LEFT   JOIN table1 t1 USING (id);

COMMIT;

fiddle

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật