如果有任何值,请选择所有值

时间:2018-06-14 08:09:12

标签: sql postgresql

我有三张桌子:

公司:

____________________________________________________________
|           id                |           company          |
____________________________________________________________
|            1                |         'Sunflower'        |
___________________________________________________________
|            2                |         'Chamomile'        |
____________________________________________________________

companies_services

____________________________________________________________
|         company             |           service          |
____________________________________________________________
|            1                |              1             |
___________________________________________________________
|            1                |              2             |
____________________________________________________________
|            2                |              1             |
____________________________________________________________

服务

____________________________________________________________
|           id                |            service         |
____________________________________________________________
|            1                |           'sales'          |
___________________________________________________________
|            2                |         'distribution'     |
____________________________________________________________

DDL SQL:

CREATE TABLE companies ("id" int, "company" varchar(9));
INSERT INTO companies ("id", "company") VALUES (1, 'Sunflower'),(2, 'Chamomile');

CREATE TABLE companies_services ("company" int, "service" int);
INSERT INTO companies_services  ("company", "service")VALUES    (1, 1), (1, 2), (2, 1);

CREATE TABLE services   ("id" int, "service" varchar(12));
INSERT INTO services    ("id", "service")VALUES (1, 'sales'),   (2, 'distribution');

和查询:

SELECT companies.company 
       services.service
FROM companies
LEFT JOIN companies_services ON comapnies.company = companies_services.company
INNER JOIN services ON companies_services.service = services.service
WHERE services.service LIKE '%distr%' 

使用此查询我只有“分发”服务,但公司可能包含更多服务,我也需要选择它们。如果公司包含服务,如果像%value%那样检查条件然后选择所有服务,否则选择什么?

结果必须类似于

____________________________________________________________
|           company           |            service         |
____________________________________________________________
|         'Sunflower'         |            'sales'         |
___________________________________________________________
|         'Sunflower'         |           'distribution'   |
____________________________________________________________

4 个答案:

答案 0 :(得分:2)

根据您的数据,我发现您不需要LEFT JOIN。这是查询>>

SELECT c.company,
       s.service
FROM   companies AS c
       INNER JOIN companies_services AS cs
              ON c.id = cs.company
       INNER JOIN services AS s
               ON cs.service = s.id
WHERE  c.id IN (SELECT c1.id
                FROM   companies AS c1
                       INNER JOIN companies_services AS cs1
                              ON c1.id = cs1.company
                       INNER JOIN services AS s1
                               ON cs1.service = s1.id
                              AND s1.service LIKE '%distr%'); 

答案 1 :(得分:1)

试一试:

with CTE as (
    select company from companies_services T1
    left join services T2 on T1.service = T2.ID
    where T2.service like '%distr%' 
)
select T3.company,T2.service from companies_services T1
left join services T2 on T1.service = T2.id
left join companies T3 on T1.company = T3.id
where T1.company in (select company from CTE)

<强>结果:

Online Test Link

答案 2 :(得分:1)

这也有效:

select companies.company, services.service  from companies
inner join (select companies_services.company from services 
            inner join companies_services on companies_services.service=services.id 
            where services.service like '%distr%') as company_id on company_id.company=companies.id
inner join companies_services on companies_services.company = companies.id
inner join services on services.id = companies_services.service

答案 3 :(得分:0)

如果您将服务放在一个列中,那么这很容易:

SELECT c.company, ARRAY_AGG(cs.service) as services
FROM companies c JOIN
     companies_services cs
     ON c.company = cs.company 
GROUP BY c.company
HAVING SUM( (cs.service LIKE '%distr%')::int ) > 0 ;

注意:

  • 不需要services表,因为您想要的列位于company_services
  • 不需要外部联接,因为您需要匹配。
  • 表别名使查询更易于阅读和写入。

如果你想分开,那么窗口功能就是你要去的地方:

SELECT company, service
FROM (SELECT c.company, cs.service,
              SUM( (cs.service LIKE '%distr%')::int ) OVER (PARTITION BY c.company) as cnt
      FROM companies c JOIN
           companies_services cs
           ON c.company = cs.company 
     ) c
WHERE cnt > 0;