Case expression to override another case expression and input the same value for 2 rows

Employee is assigned to multiple business units and based on business units an ‘Individual type’ is derived.

Individual type
Point 1. Considered to be individual type ‘IA’ if they don’t have another business unit from point 2 and is only in DIST or CS-IA, GS-IA

Point 2. Considered to be individual type ‘EMP’ if an employee is in any of these business unit – CI-CLMS, CI-DIST , GS-CLMS, GS-DIST, PL-CLMS, SFCLMS, PI-CRC, PI-DRC, PI-FLDSLS, PI-HODST , EXTLV. Anyone with these BU’s should be ‘EMP’ regardless of them having other business units like DIST or PI-IA/CI-Clms

Point 3. Considered to be individual type ‘CWK’ if an employee is in any of these business unit – PI-IA, CI-Clms or PI-temp and not in business units from** point 2.**

select 
 distinct
    i.lastname,
    I.firstname,
    I.empnumber, 
    b.businessunit,
case 
when b.businessunit = 'DIST' or b.businessunit in ('CI-IA_1')
    THEN 'IA'
when b.businessunit in ('PLCLM8-BI') 
        or b.businessunit in ( 'PI-FldSls2') 
        or b.businessunit in ('PI-HODst4' ) 
        or b.businessunit in ('EXTLV')
    THEN 'EMP'
When b.businessunit in ('CI-ClmsTA') 
    THEN 'CWK'
END
as 'individualtype'
from
individual i left join businessunit b
on i.internalid = b.internalid
WHERE I.status IN ('Active','Inactive','Pending') 
      AND B.status = 'ACTIVE' 
      and i.empnumber = '1617413' 

Result I’m getting now:

lastname firstname empnumber businessunit individualtype
Doe John 1617413 DIST IA
Doe John 1617413 PI-FldSls2 EMP

Expected Result:

lastname firstname empnumber businessunit individualtype
Doe John 1617413 DIST EMP
Doe John 1617413 PI-FldSls2 EMP

individual table

lastname firstname empnumber internalid
Doe John 1617413 1
Line Sam 2034567 2
Dot Jane 1256789 3
Doe James 2768902 4

businessunit table

empnumber businessunit internalid
1617413 DIST 1
1617413 PI-FldSls2 1
2034567 EXTLV 2
2034567 PI-FldSls2 2
2034567 PI-HODst4 2
2034567 PLCLM8-BI 2
1256789 DIST 3
1256789 CI-ClmsTA 3
2768902 DIST 4
2768902 CI-IA_1 4

New contributor

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

10

In order to get EMP as an individual type value the businessunit must satisfy this part of the case expression:

when b.businessunit in ('PLCLM8-BI') 
        or b.businessunit in ( 'PI-FldSls2') 
        or b.businessunit in ('PI-HODst4' ) 
        or b.businessunit in ('EXTLV')
    THEN 'EMP'

DIST is not in this list.

2

As I understand your problem, if any of the business units for a given individual fall into the “EMP” group, then that individual is considered an “EMP”. Otherwise, if any of the business units for that individual fall into the “IA” or “CWK” groups, that individual is considered a “IA” or “CWK”, respectfully.

Your logic does not address the possibility of an individual having both “IA” and “CWK” business units, but I’ll assume that “IA” supersedes “CWK”.

To get your desired results, you need to:

  1. Map all of the business units to individual types. Although this can be done with an embedded case expression, it would be much better to have a some kind of lookup table that defines this mapping. This reduces code clutter and should improve maintainability.
  2. For each individual, we need to scan all of the business units and mapped individual types for that individual and pick the select the top preferred individual type for whatever mix we might have. This can be done with a combination of a case expression, window functions, and conditional aggregation.

The business unit to type mapping would be something like:

CREATE TABLE businessunittype (
    businessunit VARCHAR(50),
    businessunittype VARCHAR(50)
)

INSERT INTO businessunittype
VALUES
    ('DIST',       'IA'),
    ('CS-IA',      'IA'),
    ('GS-IA',      'IA'),
    ('CI-CLMS',    'EMP'),
    ...,
    ('EXTLV',      'EMP'),
    ('PI-IA',      'CWK'),
    ('CI-Clms',    'CWK'),
    ('PI-temp',    'CWK')

The query would be something like:

select
    i.lastname, i.firstname, i.empnumber, b.businessunit, bt.businessunittype,
    case
        when count(case when bt.businessunittype = 'EMP' THEN 1 END)
             over(partition by i.empnumber) > 0 then 'EMP'  -- Point 2 
        when count(case when bt.businessunittype = 'IA' THEN 1 END)
             over(partition by i.empnumber) > 0 then 'IA'   -- Point 2
        when count(case when bt.businessunittype = 'CWK' THEN 1 END)
             over(partition by i.empnumber) > 0 then 'CWK'  -- Point 3
        else 'Other'
        end AS individualtype
from individual i
join businessunit b
    on b.internalid = i.internalid
left join businessunittype bt
    on bt.businessunit = b.businessunit
order by i.empnumber, b.internalid

There are likely other ways this logic could be refactored, such as wrapping the individualtype logic up in a CTE or subquery and then joining it with other data in the final select. The businessunittype table could have other forms, such as having flag bits instead of a text field to indicate the mapped type.

Results (with some missing business unit mappings applied and extra test data):

lastname firstname empnumber businessunit businessunittype individualtype
Dot Jane 1256789 DIST IA EMP
Dot Jane 1256789 CI-ClmsTA EMP EMP
Doe John 1617413 DIST IA EMP
Doe John 1617413 PI-FldSls2 EMP EMP
Line Sam 2034567 EXTLV EMP EMP
Line Sam 2034567 PI-FldSls2 EMP EMP
Line Sam 2034567 PI-HODst4 EMP EMP
Line Sam 2034567 PLCLM8-BI ??? EMP
Doe James 2768902 DIST IA IA
Doe James 2768902 CI-IA_1 ??? IA
Contract Worker 9900001 PI-IA CWK CWK
Contract Worker 9900001 PI-temp CWK CWK
Mixed IA/CWK 9900002 GS-IA IA IA
Mixed IA/CWK 9900002 PI-temp CWK IA
Unknown Unknown 9900003 PLCLM8-BI ??? Other

See this db<>fiddle for a demo.

0

I think you absolutely “need” a mapping table that holds the type for each emp number, to avoid horrible, extremely complex queries. Then in future you just need to fill this table. I would make this table as simple as possible and use a trivial JOIN.

So the table could for example be like this:

CREATE TABLE individual_types 
(empnumber varchar(100),
individualtype varchar(100),
description varchar(100));

The description column is optional, you could save there an information what EMP, IA etc. means. You could also add a foreign key to the emp number if you want.

Then your query will be quite simple and produce the expected result:

SELECT 
  i.lastname,
  i.firstname,
  i.empnumber, 
  b.businessunit,
  t.individualtype
FROM
  individual i LEFT JOIN businessunit b
    ON i.internalid = b.internalid
  INNER JOIN individual_types t
    ON i.empnumber = t.empnumber
  WHERE 
    i.status IN ('Active','Inactive','Pending') 
    AND b.status = 'ACTIVE' 
    AND i.empnumber = '1617413';

The only question is how to fill the mapping table. The most tricky part is the initially insertion.

For future emp numbers, you can use your application (clean) or a trigger (ugly) to fill the table and simply enter the logic there.

In order to fill the table correctly for the already existing emp numbers, you need to write an insert command with the exact logic you want.

I’m not entirely sure if I understand your intended logic correctly, but you should be able to fix it if I made a mistake. It should be something like this:

INSERT INTO individual_types (empnumber, individualtype)
SELECT
  i.empnumber,
  CASE WHEN
        COUNT(
          CASE WHEN b.businessunit IN ('CI-CLMS', 'CI-DIST', 'GS-CLMS', 'GS-DIST', 
                                       'PL-CLMS', 'SFCLMS', 'PI-CRC', 'PI-DRC', 
                                       'PI-FLDSLS','PI-HODST','EXTLV') THEN 1 END) > 0
        THEN 'EMP'
        WHEN COUNT(*) = COUNT(
          CASE WHEN b.businessunit IN ('DIST','CS-IA','GS-IA') THEN 1 END) 
        THEN 'IA'
        WHEN COUNT(
          CASE WHEN b.businessunit IN ('PI-IA', 'CI-Clms', 'PI-temp') THEN 1 END) > 0
          AND COUNT(
          CASE WHEN b.businessunit IN ('CI-CLMS', 'CI-DIST', 'GS-CLMS', 'GS-DIST', 
                                       'PL-CLMS', 'SFCLMS', 'PI-CRC', 'PI-DRC', 
                                       'PI-FLDSLS','PI-HODST','EXTLV') THEN 1 END) = 0
        THEN 'CWK'
        ELSE 'Other'
        END
FROM 
  individual i LEFT JOIN businessunit b
    ON i.internalid = b.internalid
GROUP BY
  i.empnumber;

If you have the optional description column, I would update it after the insertion.

See this sample fiddle that shows the idea is basically working. Adjust the insert command if necessary.

Notes: Of course, you could also produce the result without creating a table (that’s why I wrote “need”, not need).

In this case, you would use the query not to insert rows to your mapping table, but in a CTE that you join to your main query.

Or you could only create another column in your existing table rather than creating a whole table.

But I think a mapping table is clever and makes things easier.

You could, if you create a mapping table, also do this in other ways, as for example shown in this answer.

There are lot of options how to do what you want and it’s up to you to decide what’s the “best”. Depends on your use case(s).

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

Case expression to override another case expression and input the same value for 2 rows

Employee is assigned to multiple business units and based on business units an ‘Individual type’ is derived.

Individual type
Point 1. Considered to be individual type ‘IA’ if they don’t have another business unit from point 2 and is only in DIST or CS-IA, GS-IA

Point 2. Considered to be individual type ‘EMP’ if an employee is in any of these business unit – CI-CLMS, CI-DIST , GS-CLMS, GS-DIST, PL-CLMS, SFCLMS, PI-CRC, PI-DRC, PI-FLDSLS, PI-HODST , EXTLV. Anyone with these BU’s should be ‘EMP’ regardless of them having other business units like DIST or PI-IA/CI-Clms

Point 3. Considered to be individual type ‘CWK’ if an employee is in any of these business unit – PI-IA, CI-Clms or PI-temp and not in business units from** point 2.**

select 
 distinct
    i.lastname,
    I.firstname,
    I.empnumber, 
    b.businessunit,
case 
when b.businessunit = 'DIST' or b.businessunit in ('CI-IA_1')
    THEN 'IA'
when b.businessunit in ('PLCLM8-BI') 
        or b.businessunit in ( 'PI-FldSls2') 
        or b.businessunit in ('PI-HODst4' ) 
        or b.businessunit in ('EXTLV')
    THEN 'EMP'
When b.businessunit in ('CI-ClmsTA') 
    THEN 'CWK'
END
as 'individualtype'
from
individual i left join businessunit b
on i.internalid = b.internalid
WHERE I.status IN ('Active','Inactive','Pending') 
      AND B.status = 'ACTIVE' 
      and i.empnumber = '1617413' 

Result I’m getting now:

lastname firstname empnumber businessunit individualtype
Doe John 1617413 DIST IA
Doe John 1617413 PI-FldSls2 EMP

Expected Result:

lastname firstname empnumber businessunit individualtype
Doe John 1617413 DIST EMP
Doe John 1617413 PI-FldSls2 EMP

individual table

lastname firstname empnumber internalid
Doe John 1617413 1
Line Sam 2034567 2
Dot Jane 1256789 3
Doe James 2768902 4

businessunit table

empnumber businessunit internalid
1617413 DIST 1
1617413 PI-FldSls2 1
2034567 EXTLV 2
2034567 PI-FldSls2 2
2034567 PI-HODst4 2
2034567 PLCLM8-BI 2
1256789 DIST 3
1256789 CI-ClmsTA 3
2768902 DIST 4
2768902 CI-IA_1 4

New contributor

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

10

In order to get EMP as an individual type value the businessunit must satisfy this part of the case expression:

when b.businessunit in ('PLCLM8-BI') 
        or b.businessunit in ( 'PI-FldSls2') 
        or b.businessunit in ('PI-HODst4' ) 
        or b.businessunit in ('EXTLV')
    THEN 'EMP'

DIST is not in this list.

2

As I understand your problem, if any of the business units for a given individual fall into the “EMP” group, then that individual is considered an “EMP”. Otherwise, if any of the business units for that individual fall into the “IA” or “CWK” groups, that individual is considered a “IA” or “CWK”, respectfully.

Your logic does not address the possibility of an individual having both “IA” and “CWK” business units, but I’ll assume that “IA” supersedes “CWK”.

To get your desired results, you need to:

  1. Map all of the business units to individual types. Although this can be done with an embedded case expression, it would be much better to have a some kind of lookup table that defines this mapping. This reduces code clutter and should improve maintainability.
  2. For each individual, we need to scan all of the business units and mapped individual types for that individual and pick the select the top preferred individual type for whatever mix we might have. This can be done with a combination of a case expression, window functions, and conditional aggregation.

The business unit to type mapping would be something like:

CREATE TABLE businessunittype (
    businessunit VARCHAR(50),
    businessunittype VARCHAR(50)
)

INSERT INTO businessunittype
VALUES
    ('DIST',       'IA'),
    ('CS-IA',      'IA'),
    ('GS-IA',      'IA'),
    ('CI-CLMS',    'EMP'),
    ...,
    ('EXTLV',      'EMP'),
    ('PI-IA',      'CWK'),
    ('CI-Clms',    'CWK'),
    ('PI-temp',    'CWK')

The query would be something like:

select
    i.lastname, i.firstname, i.empnumber, b.businessunit, bt.businessunittype,
    case
        when count(case when bt.businessunittype = 'EMP' THEN 1 END)
             over(partition by i.empnumber) > 0 then 'EMP'  -- Point 2 
        when count(case when bt.businessunittype = 'IA' THEN 1 END)
             over(partition by i.empnumber) > 0 then 'IA'   -- Point 2
        when count(case when bt.businessunittype = 'CWK' THEN 1 END)
             over(partition by i.empnumber) > 0 then 'CWK'  -- Point 3
        else 'Other'
        end AS individualtype
from individual i
join businessunit b
    on b.internalid = i.internalid
left join businessunittype bt
    on bt.businessunit = b.businessunit
order by i.empnumber, b.internalid

There are likely other ways this logic could be refactored, such as wrapping the individualtype logic up in a CTE or subquery and then joining it with other data in the final select. The businessunittype table could have other forms, such as having flag bits instead of a text field to indicate the mapped type.

Results (with some missing business unit mappings applied and extra test data):

lastname firstname empnumber businessunit businessunittype individualtype
Dot Jane 1256789 DIST IA EMP
Dot Jane 1256789 CI-ClmsTA EMP EMP
Doe John 1617413 DIST IA EMP
Doe John 1617413 PI-FldSls2 EMP EMP
Line Sam 2034567 EXTLV EMP EMP
Line Sam 2034567 PI-FldSls2 EMP EMP
Line Sam 2034567 PI-HODst4 EMP EMP
Line Sam 2034567 PLCLM8-BI ??? EMP
Doe James 2768902 DIST IA IA
Doe James 2768902 CI-IA_1 ??? IA
Contract Worker 9900001 PI-IA CWK CWK
Contract Worker 9900001 PI-temp CWK CWK
Mixed IA/CWK 9900002 GS-IA IA IA
Mixed IA/CWK 9900002 PI-temp CWK IA
Unknown Unknown 9900003 PLCLM8-BI ??? Other

See this db<>fiddle for a demo.

0

I think you absolutely “need” a mapping table that holds the type for each emp number, to avoid horrible, extremely complex queries. Then in future you just need to fill this table. I would make this table as simple as possible and use a trivial JOIN.

So the table could for example be like this:

CREATE TABLE individual_types 
(empnumber varchar(100),
individualtype varchar(100),
description varchar(100));

The description column is optional, you could save there an information what EMP, IA etc. means. You could also add a foreign key to the emp number if you want.

Then your query will be quite simple and produce the expected result:

SELECT 
  i.lastname,
  i.firstname,
  i.empnumber, 
  b.businessunit,
  t.individualtype
FROM
  individual i LEFT JOIN businessunit b
    ON i.internalid = b.internalid
  INNER JOIN individual_types t
    ON i.empnumber = t.empnumber
  WHERE 
    i.status IN ('Active','Inactive','Pending') 
    AND b.status = 'ACTIVE' 
    AND i.empnumber = '1617413';

The only question is how to fill the mapping table. The most tricky part is the initially insertion.

For future emp numbers, you can use your application (clean) or a trigger (ugly) to fill the table and simply enter the logic there.

In order to fill the table correctly for the already existing emp numbers, you need to write an insert command with the exact logic you want.

I’m not entirely sure if I understand your intended logic correctly, but you should be able to fix it if I made a mistake. It should be something like this:

INSERT INTO individual_types (empnumber, individualtype)
SELECT
  i.empnumber,
  CASE WHEN
        COUNT(
          CASE WHEN b.businessunit IN ('CI-CLMS', 'CI-DIST', 'GS-CLMS', 'GS-DIST', 
                                       'PL-CLMS', 'SFCLMS', 'PI-CRC', 'PI-DRC', 
                                       'PI-FLDSLS','PI-HODST','EXTLV') THEN 1 END) > 0
        THEN 'EMP'
        WHEN COUNT(*) = COUNT(
          CASE WHEN b.businessunit IN ('DIST','CS-IA','GS-IA') THEN 1 END) 
        THEN 'IA'
        WHEN COUNT(
          CASE WHEN b.businessunit IN ('PI-IA', 'CI-Clms', 'PI-temp') THEN 1 END) > 0
          AND COUNT(
          CASE WHEN b.businessunit IN ('CI-CLMS', 'CI-DIST', 'GS-CLMS', 'GS-DIST', 
                                       'PL-CLMS', 'SFCLMS', 'PI-CRC', 'PI-DRC', 
                                       'PI-FLDSLS','PI-HODST','EXTLV') THEN 1 END) = 0
        THEN 'CWK'
        ELSE 'Other'
        END
FROM 
  individual i LEFT JOIN businessunit b
    ON i.internalid = b.internalid
GROUP BY
  i.empnumber;

If you have the optional description column, I would update it after the insertion.

See this sample fiddle that shows the idea is basically working. Adjust the insert command if necessary.

Notes: Of course, you could also produce the result without creating a table (that’s why I wrote “need”, not need).

In this case, you would use the query not to insert rows to your mapping table, but in a CTE that you join to your main query.

Or you could only create another column in your existing table rather than creating a whole table.

But I think a mapping table is clever and makes things easier.

You could, if you create a mapping table, also do this in other ways, as for example shown in this answer.

There are lot of options how to do what you want and it’s up to you to decide what’s the “best”. Depends on your use case(s).

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