Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 存在与否?_Sql_Database_Database Design_Relational Database_Relational Algebra - Fatal编程技术网

Sql 存在与否?

Sql 存在与否?,sql,database,database-design,relational-database,relational-algebra,Sql,Database,Database Design,Relational Database,Relational Algebra,考虑产品数据库的以下架构: 零件(pid,pname) 供应商(sid、sname) 目录(sid,pid) Catalog中的sid是外键,参考供应商,Catalog中的pid是外键,参考零件表(s1,p1)目录中的表显示供应商s1生产p1 如果我想找到一些供应商未提供的零件的详细信息,我们如何做到这一点?我读了以下部分: SELECT * FROM parts P WHERE ....... (SELECT S.sid FROM suppliers

考虑产品数据库的以下架构:

  • 零件
    (pid,pname)
  • 供应商
    (sid、sname)
  • 目录
    (sid,pid)
Catalog
中的
sid
是外键,参考
供应商
Catalog
中的
pid
是外键,参考
零件
表<代码>(s1,p1)目录中的
表显示供应商
s1
生产
p1

如果我想找到一些供应商未提供的
零件的详细信息,我们如何做到这一点?我读了以下部分:

SELECT *
FROM parts P
WHERE ....... (SELECT S.sid 
               FROM suppliers 
                WHERE .....
                       (SELECT * 
                        FROM catalog C 
                        WHERE s.sid = C.sid AND P.pid = C.pid))

我的问题是,为什么一开始?我们使用exist和in second。。。我们使用不存在?

难道不是这么简单吗?如果没有,请使用我的示例表并指定您的预期输出:

DECLARE @Parts TABLE(pid INT, pname VARCHAR(100));
DECLARE @Suppliers TABLE(sid INT, sname VARCHAR(100));
DECLARE @Catalog TABLE(pid INT, sid INT);

INSERT INTO @Parts VALUES(1,'Part 1'),(2,'Part 2'),(3,'Part 3'),(4,'Part 4');
INSERT INTO @Suppliers VALUES(1,'Suppl 1'),(2,'Suppl 2'),(3,'Suppl 3');
INSERT INTO @Catalog VALUES(1,1),(1,3) --part 1 from two suppliers
                          ,(2,1)       --part 2 from one supplier
                                       --part 3 no supplier
                                       --part 4 no supplier

--Get all parts *that not supplied by some suppliers*
SELECT * 
FROM @Parts AS p 
WHERE p.pid NOT IN(SELECT c.pid FROM @Catalog AS c) 
结果

pid pname
3   Part 3
4   Part 4
编辑:“您的”查询也会达到同样的效果,但这会执行得更糟: 此查询正在查找零件,其中没有供应商在“目录”中有条目。我必须承认,这闻起来有点像家庭作业:-)


不是这么简单吗?如果没有,请使用我的示例表并指定您的预期输出:

DECLARE @Parts TABLE(pid INT, pname VARCHAR(100));
DECLARE @Suppliers TABLE(sid INT, sname VARCHAR(100));
DECLARE @Catalog TABLE(pid INT, sid INT);

INSERT INTO @Parts VALUES(1,'Part 1'),(2,'Part 2'),(3,'Part 3'),(4,'Part 4');
INSERT INTO @Suppliers VALUES(1,'Suppl 1'),(2,'Suppl 2'),(3,'Suppl 3');
INSERT INTO @Catalog VALUES(1,1),(1,3) --part 1 from two suppliers
                          ,(2,1)       --part 2 from one supplier
                                       --part 3 no supplier
                                       --part 4 no supplier

--Get all parts *that not supplied by some suppliers*
SELECT * 
FROM @Parts AS p 
WHERE p.pid NOT IN(SELECT c.pid FROM @Catalog AS c) 
结果

pid pname
3   Part 3
4   Part 4
编辑:“您的”查询也会达到同样的效果,但这会执行得更糟: 此查询正在查找零件,其中没有供应商在“目录”中有条目。我必须承认,这闻起来有点像家庭作业:-)

如果我想找到一些供应商未提供的
零件的详细信息,我们如何做到这一点

如果您想要“存在不提供该零件的供应商的零件的详细信息”,则使用
exists
然后
NOT exists
的查询是正确的

我的问题是,为什么一开始?我们使用exist和in second。。。我们不存在吗

我将解释为什么“存在不提供该零件的供应商的零件详细信息”可以给出您的查询。(如果
存在
不存在

一个表包含将某些谓词(语句模板)转换为真命题(语句)的行:

  • 零件
    “零件P.pid命名为P.pname”
  • 供应商
    “供应商S.sid命名为S.sname”
  • 目录
    “供应商C.sid提供零件C.pid”
您需要表示结果的谓词。您希望
P.pid
-
P.pname
行从以下内容生成一个真正的语句:

    "part P.pid is named P.pname"
AND EXISTS S.sid ["supplier S.sid is named something"
        AND NOT "supplier S.sid supplies part P.pid"]
但我们必须用给定的谓词(加上条件和逻辑运算符)来表示该谓词,以便DBMS可以计算满足该谓词的行:

    "part P.pid is named P.pname"
AND EXISTS S.sid [EXISTS S.sname "supplier S.sid is named S.sname"
        AND NOT EXISTS C.sid, C.pid [
                "supplier C.sid supplies part P.pid" AND C.sid = S.sid AND C.pid = P.pid]]
现在转换为SQL:

  • T的初始谓词从
T
  • T的谓语变成
    JOIN
    T
  • 并且条件变为
    ,其中
    条件
    上的
    条件
  • 最外层的已删除列变为
    SELECT
    保留列
  • 其他存在T的所有列[T的谓词]变为
    存在(
    T
  • PS您的问题的原始“部分供应商未提供的零件的详细信息”不清楚/不明确。它可能表示
    P.id
    -
    P.pname
    对,其中:

  • “并非所有供应商都提供零件”(解释与您的SQL一致)
  • “零件不是(由任何供应商)提供的”(解释与中的两个SQL版本一致)
  • “零件没有多个供应商”

    上述PPS逻辑公式如下:

    -- 1. "the parts are not supplied by all the suppliers"  
        P(P.pid, P.pname)
    AND EXISTS S.sid, S.sname [S(S.sid, S.sname) AND NOT C(S.sid, P.pid)]
    -- 2 "the parts are not supplied (by some of the suppliers)"
    P(P.pid, P.pname) AND NOT EXISTS C.sid C(C.sid, P.pid)
    -- 3. "the parts don't have multiple suppliers"
        P(P.pid, P.pname)
    AND NOT EXISTS C1.sid, C2.sid
            [C(C1.sid, P.pid) AND C(C2.sid, P.pid) AND C1.sid <> C2.sid]
    
    --1.“并非所有供应商都提供零件”
    P(P.pid,P.pname)
    并且存在S.sid,S.sname[S(S.sid,S.sname)而不是C(S.sid,P.pid)]
    --2“部分供应商未提供零件”
    P(P.pid,P.pname)且不存在C.sid C(C.sid,P.pid)
    --3.“零件没有多个供应商”
    P(P.pid,P.pname)
    并且不存在C1.sid,C2.sid
    [C(C1.sid,P.pid)和C(C2.sid,P.pid)以及C1.sid C2.sid]
    
    如果我想找到一些供应商未提供的
    零件的详细信息,我们如何做到这一点

    如果您想要“存在不提供该零件的供应商的零件的详细信息”,则使用
    exists
    然后
    NOT exists
    的查询是正确的

    我的问题是通过-为什么一开始?我们使用存在,第二次…我们使用不存在

    我将解释为什么“存在不提供该零件的供应商的零件的详细信息”可以给出您的查询。(使用
    存在
    然后
    不存在

    一个表包含将某些谓词(语句模板)转换为真命题(语句)的行:

    • 零件
      “零件P.pid命名为P.pname”
    • 供应商
      “供应商S.sid命名为S.sname”
    • 目录
      “供应商C.sid提供零件C.pid”
    您需要表示结果的谓词。您需要
    p.pid
    -
    p.pname
    行,这些行从以下内容生成一个真正的语句:

        "part P.pid is named P.pname"
    AND EXISTS S.sid ["supplier S.sid is named something"
            AND NOT "supplier S.sid supplies part P.pid"]
    
    但我们必须用给定的谓词(加上条件和逻辑运算符)来表示该谓词,以便DBMS可以计算满足该谓词的行:

        "part P.pid is named P.pname"
    AND EXISTS S.sid [EXISTS S.sname "supplier S.sid is named S.sname"
            AND NOT EXISTS C.sid, C.pid [
                    "supplier C.sid supplies part P.pid" AND C.sid = S.sid AND C.pid = P.pid]]
    
    现在转换为SQL:

    • T的初始谓词从
    T
  • T的谓语变成
    JOIN
    T
  • 并且条件变为
    ,其中
    条件
    上的
    条件
  • 最外层的已删除列变为
    SELECT
    保留列
  • 其他存在T的所有列[T的谓词]变为
    存在(
    T
  • PS你的问题'