带有MINUS INTERSECT和UNION的SELECT子句

时间:2014-05-05 16:01:06

标签: sql oracle

在我的数据库中,我创建了一个表名DEPTLOC

//DEPTLOC
DNAME               CITY
----------------------------
RESEARCH          BOSTON
  IT              PARIS
 SCIENCE          LONDON
RESEARCH          LONDON
 SALES            NEWYORK
RESEARCH          PARIS
RESEARCH          NEWYORK
MARKETING         NEWYORK

所以我使用了以下查询

SELECT CITY FROM DEPTLOC 
INTERSECT
(
 SELECT CITY FROM DEPTLOC WHERE DNAME='SALES'
 UNION 
 SELECT CITY FROM DEPTLOC WHERE DNAME='RESEARCH'
);

但我的输出是所有CITY都会显示。我的问题是想找出哪个DNAME =' SALES'或DNAME ='研究'它位于所有城市。

所以从上表可以看出,所有不同的城市都是

CITY
-------
BOSTON
PARIS
LONDON
NEWYORK

自'研究'拥有所有的位置,但'销售'只有一些,我的输出应该像这样显示

DNAME
---------
RESEARCH

为了获得正确的输出,我应该为我的查询更改

4 个答案:

答案 0 :(得分:0)

这样做的一种方法是计算不同的位置,并将其加入部门查询:

SELECT dname
FROM   (SELECT   dname, COUNT(*) AS dept_city_count
        FROM     deptloc
        GROUP BY dname) d
JOIN   (SELECT COUNT (DISTINCT city) AS city_count
        FROM   deptloc) ON city_count = dept_cirt_count

答案 1 :(得分:0)

这是一个使用连接的查询。首先选择所有城市。然后,在所有部门和所有城市之间建立CROSS JOIN。然后,LEFT JOIN用于选择没有所有城市的部门。然后,另一个LEFT JOIN用于选择具有所有城市的部门。

SELECT DISTINCT
  DL.DNAME
FROM
  DEPTLOC DL
LEFT JOIN
  (
    SELECT 
      ALL_COMBOS.DNAME dname
    FROM
      (
        SELECT DISTINCT
          D1.DNAME DNAME,
          D2.CITY CITY
        FROM
          DEPTLOC D1
        CROSS JOIN
          (
            SELECT DISTINCT
              CITY
            FROM
              DEPTLOC
          )
          D2 --All distinct Cities
      )
      ALL_COMBOS --All Departments with all Locations
    LEFT JOIN DEPTLOC D2
    ON
      ALL_COMBOS.DNAME  = D2.DNAME
    AND ALL_COMBOS.CITY = D2.CITY
    WHERE
      D2.DNAME IS NULL
  )
  NOT_ALL_LOCATIONS --Departments that do not have all Locations
  ON DL.DNAME = NOT_ALL_LOCATIONS.DNAME
WHERE
  NOT_ALL_LOCATIONS.DNAME IS NULL; --Departments that have all Locations

可以看出,这种方法不依赖于城市的数量,而是依赖于城市本身的实际价值。

答案 2 :(得分:0)

假设deptloc中的密钥是(dname,city),那么以下内容将起作用:

select dname
  from deptloc
 group by dname
 having count(*) = (select count(distinct city) from deptloc);

查询的工作原理是为每个部门创建一个组。计数(*)将是该部门所在城市的nr。每个这样的计数与同一表中引用的nr个独特城市进行比较。

已编辑:现在看到您的评论,这是您不想要的解决方案:)

这是"关系师的另一个版本"

select departments.dname 
  from (select distinct dname from deptloc) departments
 where not exists(
   select 'x'
     from (select distinct city from deptloc) cities
    where not exists(
      select 'x'
        from deptloc x
       where x.city  = cities.city
         and x.dname = departments.dname));                       

答案 3 :(得分:0)

这里的查询(仅比我之前的答案)更短,只检查DNAMES SALES和RESEARCH,以查看哪个DNAME具有所有CITIES。设置运算符UNION ALL和MINUS。

SELECT DNAME 
FROM
(
  SELECT 'SALES' DNAME, COUNT(*) MISSING_CITIES
  FROM
  (
    SELECT DISTINCT CITY FROM DEPTLOC
      MINUS
    SELECT CITY FROM DEPTLOC WHERE DNAME = 'SALES'
  )
  UNION ALL
  SELECT 'RESEARCH', COUNT(*) FROM
  (
    SELECT DISTINCT CITY FROM DEPTLOC
      MINUS
    SELECT CITY FROM DEPTLOC WHERE DNAME = 'RESEARCH'
  )
)
WHERE MISSING_CITIES = 0;