2

我在 sql server 2008 中有下表,其中包含医院 ID 及其部门:

HID    DEPT
5   neuro
2   derma
3   cardio
2   ent
1   neuro
5   optha
3   ent
3   optha
4   derma
1   optha
5   derma

需要使用 sql 获取它没有的 id 和部门名称列表。例如:

HID   DEPT
 1    derma
 1    cardio
 1    ent
 2    cardio
 2    neuro
 2    optha

等谢谢

4

3 回答 3

6

尝试这个:

;WITH CTE AS
(
    SELECT *
    FROM (  SELECT DISTINCT HID
            FROM YourTable) A
    CROSS JOIN (SELECT DISTINCT DEPT
                FROM YourTable) B
)
SELECT *
FROM CTE A
WHERE NOT EXISTS(SELECT 1 FROM YourTable
                 WHERE HID = A.HID AND DEPT = A.DEPT)

这是一个带有演示的sqlfiddle。

于 2013-07-22T20:02:12.177 回答
3

为了使选项列表更完整,这里还有一个 EXCEPT 解决方案:

SELECT h.HID, d.DEPT
FROM       (SELECT HID  FROM atable) h
CROSS JOIN (SELECT DEPT FROM atable) d
EXCEPT
SELECT HID, DEPT
FROM atable;

根据在任一列中重复值的次数,您还可以在应用 EXCEPT 之前尝试仅交叉连接唯一值:

SELECT h.HID, d.DEPT
FROM       (SELECT DISTINCT HID  FROM atable) h
CROSS JOIN (SELECT DISTINCT DEPT FROM atable) d
EXCEPT
SELECT HID, DEPT
FROM atable;
于 2013-07-22T22:02:52.317 回答
3

对于这种类型的查询,您希望从生成所有可能组合的“驱动程序”子查询开始。然后,您left outer join对存在的内容执行 a,并选择不匹配的内容:

select driver.hid, driver.dept
from (select hid, dept
      from (select distinct hid from hd) h cross join
           (select distinct dept from hd) d
     ) driver left outer join
     hd
     on driver.hid = hd.hid and
        driver.dept = hd.dept
where hd.hid is null;

编辑:

这是带有数据的更正查询:

with hd as (
      select 5 as hid, 'neuro' as dept union all
      select 2, 'derma' union all
      select 3, 'cardio' union all
      select 2, 'ent' union all
      select 1, 'neuro' union all
      select 5, 'optha' union all
      select 3, 'ent' union all
      select 3, 'optha' union all
      select 4, 'derma' union all
      select 1, 'optha' union all
      select 5, 'derma'
     )
select driver.hid, driver.dept
from (select hid, dept
      from (select distinct hid from hd) h cross join
           (select distinct dept from hd)d
     ) driver left outer join
     hd
     on driver.hid = hd.hid and
        driver.dept = hd.dept
where hd.hid is null;

请注意,它返回的列表比问题中的要长。我认为该列表不完整。

于 2013-07-22T19:20:48.870 回答