2016-04-21 46 views
1

我似乎有问题得到某个查询工作。我知道我很亲密。这里是一个copy of my er diagramsql加入并减去

我想我是如此接近实现我想用这个代码做的事情,只有当我试图运行它时会得到无效的标识符。我认为这是因为练习在加入后有所改变,因为我只在第5行获得无效标识符?

SELECT staffid, staff_firstname, staff_surname, practice.practice_name, practice.practice_city 
from staff 
join practice on staff.practiceid = practice.practiceid 
MINUS 
SELECT staffid, staff_firstname, staff_surname, practice.practice_name, practice.practice_city 
from staff 
where role = 'GP'; 

基本上我试图使用减号构造找到不使用GP的做法,并包含一些信息,例如CITY和practice_address。

我可以用负结构,以找出有多少员工没有GP的像这样的角色:

SELECT staffid, staff_firstname, staff_surname 
from staff 
MINUS 
SELECT staffid, staff_firstname, staff_surname 
from staff 
where role = 'GP'; 

在那里我得到的结果:

STAFFID STAFF_FIRS STAFF_SURN 
__________ __________ __________ 
     8 NYSSA  THORNTON 
     9 MONA  BRADSHAW 
     10 GLORIA  PENA 

我挣扎使用加减构造的连接来获取有关GP的练习地址和城市等的信息。

任何帮助将不胜感激!

+0

减号后的seond查询未加入练习表? –

+0

哇...谢谢哈哈! – user3357649

回答

2

第二个选择,负后,指的是从实践表列 - 但它并没有加入到它:

SELECT staffid, staff_firstname, staff_surname, 
    practice.practice_name, practice.practice_city 
from staff 
join practice on staff.practiceid = practice.practiceid 
MINUS 
SELECT staffid, staff_firstname, staff_surname, 
    practice.practice_name, practice.practice_city 
from staff 
join practice on staff.practiceid = practice.practiceid 
where role = 'GP'; 

这是不会给你想要什么,虽然,它只会删除GP员工的行数,而不是所有GP的实践跟踪 - 所有实践中的非GP员工仍将显示。

如果你不想要剩下的员工细节,你只需要在选择列表中包含练习表中的列,然后减号会给你你想要的东西(Gordon Linoff已经显示了minus的两种替代方案在这种情况下)。如果你想,其余人员的详细信息,那么你可以使用一个不存在的条款,而不是minus - 是这样的:

select s.staffid, s.staff_firstname, s.staff_surname, 
    p.practice_name, p.practice_city 
from staff s 
join practice p on s.practiceid = p.practiceid 
where not exists (
    select 1 
    from staff s2 
    where s2.practice_id = p.practice_id 
    and s2.role = 'GP 
); 

这与戈登的第二查询,但有一个额外的加盟staff的细节。再一次,如果你不想要这些,使用戈登更简单的查询。

您也可以使用汇总检查,或者如果您已经了解了这些检查的功能,可以使用分析函数进行一些操作,以避免必须两次打表。

+0

我将如何使用不存在的声明呢?替换minus不存在,然后将括号括在select语句中? – user3357649

+0

@ user3357649 - 添加了一个粗糙的不存在的版本。 –

1

您的原始查询只在“员工”级别上运行,而不是“实践”级别。我会倾向于解决这个使用聚合:

select p.practice_name, p.practice_city 
from staff s join 
    practice p 
    on s.practiceid = p.practiceid 
group by p.practice_name, p.practice_city 
having sum(case when s.role = 'GP' then 1 else 0 end) = 0; 

,或者甚至更好:

select p.* 
from practice p 
where not exists (select 1 
        from staff s 
        where s.practiceid = p.practiceid and s.role = 'GP' 
       ); 

我觉得这是你的问题的最简单,最直接的解释。