我在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
等。谢谢
答案 0 :(得分: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)
Here is一个带有演示的方形小说。
答案 1 :(得分:3)
对于此类查询,您希望以生成所有可能组合的“驱动程序”子查询开始。然后,对存在的那些进行left outer join
,并选择不匹配的那些:
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;
请注意,它会返回比问题中更长的列表。我认为这个清单不完整。
答案 2 :(得分: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;