sql与动态输入集

时间:2016-10-26 18:46:59

标签: sql oracle oracle11g intersect

我正在试图弄清楚如何获得动态输入集的交集。这是一个非常简化的例子。

company_status 表格:

COMPANY | STATUS
----------------
  Big   |   1
Notused |   0
 Small  |   1

company_country 表:

COMPANY | COUNTRY
-----------------
  Big   |   CA
  Big   |   US
Notused |   CA
Notused |   FR
 Small  |   US
 Small  |   IT

我想要的只是某些公司的国家/地区的交叉点。

如果我只选择status = 1的公司,这是我预期的输出:

  

US

如果我只选择status = 0的公司,这是我预期的输出:

  

CA
  FR

将company_status表排除在等式之外,这就是我需要的:

select country from company_status where company = 'Big'
intersect
-- ... (here is where the dynamic part comes in)
intersect
select country from company_status where company = 'Small';

但是如何将company_status添加到此?

2 个答案:

答案 0 :(得分:1)

基本查询是:

select cc.country
from company_country cc join
     company_status cs
     on cc.company = cs.company
group by cc.country

然后使用having子句进行过滤。我认为这两个过滤器是:

having min(status) = max(status) and min(status) = 1
having sum(case when status = 0 then 1 else 0 end) > 0

这些对应于示例中指定的结果集。

答案 1 :(得分:1)

如果我理解正确,那么您只想要这些在company_status的每一行中满足条件状态= 1或状态= 0的国家/地区。

如果是这样,你可以计算,在company_status中可以找到多少次出现,并在having-子句中使用它。但是你当然必须在连接的where子句中加入相同的条件。

WITH 
company_status as (
  select 'BIG' COMPANY, 1 STATUS from dual union all
  select 'NOTUSED' COMPANY, 0 STATUS from dual union all
  select 'SMALL' COMPANY, 1 STATUS from dual
),
company_country as (
  select 'BIG' COMPANY, 'CA' COUNTRY from dual union all
  select 'BIG' COMPANY, 'US' COUNTRY from dual union all
  select 'NOTUSED' COMPANY, 'CA' COUNTRY from dual union all
  select 'NOTUSED' COMPANY, 'FR' COUNTRY from dual union all
  select 'SMALL' COMPANY, 'US' COUNTRY from dual union all
  select 'SMALL' COMPANY, 'IT' COUNTRY from dual
)
select cc.country
from company_country cc join
     company_status cs
     on cc.company = cs.company
where cs.status = 0
group by cc.country
having count(*) = (SELECT COUNT(*) FROM company_status where status = 0);

(with子句只给出你的行,其余的问题应该适用于你的例子)

但是您可以使用with子句来确定您只想在一个地方使用哪个状态(第三个带子句,将是您的第一个):

WITH 
company_status as (
  select 'BIG' COMPANY, 1 STATUS from dual union all
  select 'NOTUSED' COMPANY, 0 STATUS from dual union all
  select 'SMALL' COMPANY, 1 STATUS from dual
),
company_country as (
  select 'BIG' COMPANY, 'CA' COUNTRY from dual union all
  select 'BIG' COMPANY, 'US' COUNTRY from dual union all
  select 'NOTUSED' COMPANY, 'CA' COUNTRY from dual union all
  select 'NOTUSED' COMPANY, 'FR' COUNTRY from dual union all
  select 'SMALL' COMPANY, 'US' COUNTRY from dual union all
  select 'SMALL' COMPANY, 'IT' COUNTRY from dual
),
wished_status as (select 0 wished_status from dual)
select cc.country
from company_country cc 
join company_status cs on cc.company = cs.company
JOIN wished_status s on cs.status = s.wished_status
group by cc.country
having count(*) = (SELECT COUNT(*) FROM company_status cs join wished_status s on cs.status = s.wished_status);

因此您只需在wished_status

中更改0到1(或任何您需要的)