2017-11-17 110 views
1

我有两张桌子,一张是学生名单,另一张是餐厅名单。人员表格包含PK作为FK包含在餐馆表格中。餐桌包含学生喜欢在餐厅吃饭的日子(以及他们在餐厅吃饭的时间)。我试图找到周一不喜欢在餐厅用餐的学生。我尝试使用下面的查询,但它列出了所有的学生,而不是周一没有外出的那些学生。MS SQL不喜欢查询

SELECT DISTINCT SName 
FROM Dinner AS D 
INNER JOIN Student AS S ON D.SID = S.SID  
WHERE DinnerDay NOT LIKE 'Monday' 
GROUP BY SName 
+0

考虑使用'where not exists'查询。另外,使用'distinct'和'group by'都是不必要的:都返回唯一的'SName'。如果你正在汇总(sum,avg等),使用'group by',如果你只想返回唯一值,使用'distinct'。 – HoneyBadger

+0

好了,尝试了以下,但它不喜欢的NOT EXISTS语法:SELECT DISTINCT SNAME FROM晚餐d INNER JOIN学生为S \t ON D.SID = S.SID WHERE DinnerDay NOT EXISTS '星期一' –

+0

你为什么不用'<>'来代替'NOT LIKE'?您的NOT EXISTS语法错误。如果您仍想使用'NOT LIKE',请使用'NOT LIKE'Monday%'。 – user6542823

回答

1

我认为你正在寻找这个没有发现学生:

SELECT DISTINCT SName 
FROM Student AS S 
WHERE NOT EXISTS (
         SELECT  NULL 
         FROM  Dinner AS D 
         WHERE  DinnerDay = 'Monday' 
           AND D.SID = S.SID 
        ) 
+0

我试过这种语法,但它没有返回任何结果。 –

+0

我犯了一个小错误,请参阅编辑。你已经有了一个答案,但它从来没有伤害有替代品。 – HoneyBadger

+0

真棒,这个工程现在,谢谢一堆 –

0
SELECT DISTINCT SName 
FROM Dinner AS D 
INNER JOIN Student AS S ON D.SID = S.SID  
WHERE DinnerDay <> 'Monday' 

尝试使用<>

+0

<>似乎没有解决它,但得到了下面的答案。 –

1

您可以使用学生表和子查询。子查询是周一用餐的所有学生的明确列表,然后运行学生和子查询b的左外连接,其中b.SID为空;

select S.SName from Student as S 
Left Outer Join 
(select Distinct S2.SID from Student as S2 Inner Join Dinner as D on S2.SID=D.SID where D.DinnerDay='Monday') as tbMonStd 
on S.SID=tbMonStd.SID 
where tbMonStd.SID IS NULL 

子查询为您提供了附加到周一所有学生的列表。左外连接和最后的where子句让你在周一列表

+0

谢谢,这个工作。我只需要分解语法来理解它。再次感谢您 –

0

内部联接将删除不就加盟条件相匹配的行。所以你可以让学生从不吃任何一家餐馆,因为内心的加入会消除这些学生。相反,你应该使用左连接,它将返回null。

你也做了DISTINCTGROUP BY。这是删除重复两次。你只需要做其中的一个。

SELECT DISTINCT CASE WHEN (D.ID IS NOT NULL) 
         THEN S.SName 
       END 
FROM Student AS S 
LEFT JOIN Dinner AS D ON S.SID = D.SID AND D.DinnerDay = 'Monday' 

这将返回NULL为D.ID如果学生没有在周一吃,或在任何餐厅从来不吃了。案例陈述检查是否D.ID IS NOT NULL,如果是,则返回S.SName。这个选择是DISTINCT删除重复项。