我在SQL中没有正确的答案

我在SQL中没有正确的答案,sql,Sql,列出项目编号PR_NO,这些项目仅接收存储在p_CITY中的零件,p_CITY与项目显示查询输出的城市相同 表:环境管理计划 主键:E_NO E_NO E_NAME E_RATE E_DEPT 1 A $400.00 2 B $200.00 1 3 C $150.00 2 4 D $150.00 3 5 E $120.00 1 6

列出项目编号PR_NO,这些项目仅接收存储在p_CITY中的零件,p_CITY与项目显示查询输出的城市相同

表:环境管理计划 主键:E_NO

E_NO    E_NAME  E_RATE  E_DEPT
1          A    $400.00 
2          B    $200.00   1
3          C    $150.00   2
4          D    $150.00   3
5          E    $120.00   1
6          F    $100.00   1
7          G    $100.00   2
8          H    $50.00    2
9          I    $50.00    3
10         J    $50.00    3
11         K    $150.00   3
表:部分 主键:P_编号

P_NO    P_NAME  P_CITY
1         P1    NY
2         P2    NY
3         P3    LA
4         P4    SF
5         P5    LA
6         P6    NY
表:项目 主键:PR_NO

PR_NO   PR_MGR  PR_DEPT PR_LOC
1           2         1     NY
2           3         2     LA
3           2         1     NY
表:供应商 主键:S_NO

S_NO    S_NAME  S_LOC
1          S1    NY
2          S2    NY
3          S3    LA
表:供应

Primary Key: P_NO + PR_NO + S_NO
Foreign Key: P_NO references PART
Foreign Key: PR_NO references PROJECT
Foreign Key: S_NO references SUPPLIER

P_NO    PR_NO   S_NO    QTY
1          1    1       111
1          1    2       112
1          1    3       113
1          2    1       121
1          2    2       122
1          2    3       123
1          3    1       131
1          3    2       132
1          3    3       133
2          1    1       211
3          1    1       311
4          1    1       411
5          1    1       511
6          1    1       611
表:工作

Primary Key: E_NO + PR_NO
Foreign Key: E_NO references EMP
Foreign Key: PR_NO references PROJECT
E_NO    PR_NO   HRS
2          1    10
3          2    20
5          1    20
5          2    20
5          3    20
6          1    10
6          2    10



select distinct P.PR_NO
from PROJECT P, PART PA
where PA.P_CITY = P.PR_LOC;
正确答案应该是:

PR_NO
3
这就是错误:

PR_NO
    1
    3
    2

查询中的主要问题是,在筛选之前,应该正确地联接2个表项目和部分;因此,在这种情况下,您应该使用表供应

SELECT DISTINCT S.PR_NO
  FROM SUPPLY S
  INNER JOIN PROJECT PR
  ON S.PR_NO = PR.PR_NO
  INNER JOIN PART P
  ON S.P_NO = P.P_NO
  WHERE PR.PR_LOC = P.P_CITY
  AND S.PR_NO NOT IN ( SELECT DISTINCT S.PR_NO
                         FROM SUPPLY S
                         INNER JOIN PROJECT PR
                         ON S.PR_NO = PR.PR_NO
                         INNER JOIN PART P
                         ON S.P_NO = P.P_NO
                         WHERE PR.PR_LOC <> P.P_CITY );

希望这有帮助

为了完成此任务,您还需要使用以下供应表:

select s.pr_no
from supply s
inner join part p
on p.p_no = s.p_no
group by s.pr_no
having max(p.p_city) = min(p.p_city)
and    min(p.p_city) = (select pr_loc
                        from project
                        where pr_no = s.pr_no
                       )

我用您的示例数据测试了此查询,它按预期返回项目3:

SELECT DISTINCT S.PR_NO
FROM
    SUPPLY S
    INNER JOIN PROJECT PR
        ON S.PR_NO = PR.PR_NO
    INNER JOIN PART P
        ON S.P_NO = P.P_NO
WHERE
    PR.PR_LOC = P.P_CITY AND
    NOT S.PR_NO IN
        (
            SELECT S2.PR_NO
            FROM
                SUPPLY S2
                INNER JOIN PROJECT PR2
                    ON S2.PR_NO = PR2.PR_NO
                INNER JOIN PART P2
                    ON S2.P_NO = P2.P_NO
            WHERE PR2.PR_LOC <> P2.P_CITY
        )

供应表创建零件和项目之间的链接。主查询查找与项目存储在同一城市的零件。where子句中的子select看起来几乎相同,只是它查找存储在不同城市的零件。有这样城市的项目被排除在外,没有S.PR_NO IN….

提示:你需要加入两个键。请解释为什么你认为结果应该只有3个。只有收到部分的项目-应该有第三个表。@OlivierJacot Descombes你在编辑中删除了表供应商和供应商,这对我完成这项任务很重要,即使OP的查询没有提到这些表格。如果下面的任何答案已经解决/帮助您解决了问题,请将其标记为答案和/或对答案进行投票。请注意,只有在项目所在城市的P_CITY中才有收到的部件。尽管这可能适用于某些RDBMS,您不应该在HAVING子句中访问p.p_city,因为它未在GROUP BY中列出。但是你可以用maxp.p_city=..@PaulSpiegel来解决这个问题,我想在这里检查一下,提供的收到的零件只能来自一个位置。我同意你的看法。我应该检查maxp.p_city=minp.p_city。我说得对吗。。我们知道,由于countdistinct p.p_city=1,因此只能有一个城市。您的编辑不会更改任何内容。但是RDBMS通常没有我们那么聪明;——因此,它会抱怨不知道在哪里读p.p_city,组中有多行。但是因为我们知道,只有一个城市,我们可以使用最小值或最大值来避免错误。所以我的意思是:和minp.p_city=select pr_loc…它也应该是select s.pr_no而不是s.p_noTo来证明我第一次评论中的问题-这里是一个例子。从第二个条件中删除min,您将得到一个错误:p.p_city列必须出现在GROUP BY子句中,或者在聚合函数中使用。