哪个加入SQL加查询

时间:2018-05-13 13:03:51

标签: sql oracle

我有4张桌子,我想从每张桌子中选择一列,但前提是该部门同时拥有“Mick'和Dave在其中工作(必须有两个名字,而不是一个或另一个)。但它似乎没有正常工作:

SELECT SCHOOL_NAME, TOWN, COUNTY
FROM STUDENTS 
NATURAL JOIN SCHOOLS NATURAL JOIN TOWNS NATURAL JOIN 
COUNTIES
WHERE FIRST_NAME IN ('Mick','Dave)
/

我在某个地方出错了(可能很多地方:()。任何帮助都会很棒

3 个答案:

答案 0 :(得分:1)

请勿使用NATURAL JOIN。这是令人厌恶的,因为它没有考虑到正确宣布的外键关系。它只查看列的名称。这可能会导致很难找到错误。

其次,你想要的是聚合:

select sc.SCHOOL_NAME, t.TOWN, c.COUNTY
from STUDENTS st join
     SCHOOLS sc
     on st.? = sc.? join
     TOWNS t 
     on t.? = ? join
     COUNTIES c
     on c.? = t.?
where FIRST_NAME in ('Mick', 'Dave')
group by sc.SCHOOL_NAME, t.TOWN, c.COUNTY
having count(distinct st.first_name) = 2;

?是表名和列名的占位符。如果您正在学习SQL,那么了解列如何在不同表中排列连接更为重要。

where子句只能检查单行中的值。每个学生都有一个单独的行,所以没有办法 - 仅用where - 找到两个学生。这就是汇总的地方。

答案 1 :(得分:0)

您至少需要three Join conditions,并使用引号正确结束字符串Dave

SELECT SCHOOL_NAME, TOWN, COUNTY
  FROM SCHOOLS h 
  JOIN TOWNS t ON (t.id=h.town_id) 
  JOIN COUNTIES c ON (t.county_id=c.id) 
 WHERE EXISTS ( SELECT school_id 
                  FROM STUDENTS s
                 WHERE s.first_name in ('Mick','Dave')
                   AND school_id = h.id
                GROUP BY school_id
                HAVING count(1)>1
                  );

SQL Fiddle Demo

答案 2 :(得分:0)

您可以在子查询中使用分析函数来计算每个Mick名称为Daveschool_id的学生(假设这是您学校的标识符) :

SELECT SCHOOL_NAME, TOWN, COUNTY
FROM ( SELECT *
       FROM   (
         SELECT d.*,
                COUNT(
                  DISTINCT
                  CASE WHEN FIRST_NAME IN ( 'Mick', 'Dave' ) THEN FIRST_NAME END
                ) OVER( PARTITION BY school_id )
                  AS num_matched
         FROM   STUDENTS d
       )
       WHERE num_matched = 2
     )
     NATURAL JOIN SCHOOLS
     NATURAL JOIN TOWNS
     NATURAL JOIN COUNTIES;

SQLFiddle

您最好使用INNER JOIN并明确指定加入条件,而不是依赖NATURAL JOIN