Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.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_Many To Many_Self Join - Fatal编程技术网

使用SQL,如何在单个表多对多关系中查找不匹配项?

使用SQL,如何在单个表多对多关系中查找不匹配项?,sql,many-to-many,self-join,Sql,Many To Many,Self Join,我有一个数据库,其中包括记录成分之间反应的结果。它目前由以下三个表构成: | Material | |----------------| | id : Integer | | name : Varchar | | Reaction | |-----------------| | id : Integer | | <other details> | | Ingredient | |----------------------

我有一个数据库,其中包括记录成分之间反应的结果。它目前由以下三个表构成:

| Material       |
|----------------|
| id : Integer   |
| name : Varchar |

| Reaction        |
|-----------------|
| id : Integer    |
| <other details> |

| Ingredient            |
|-----------------------|
| material_id : Integer |
| reaction_id : Integer |
| quantity : Real       |
|材料|
|----------------|
|id:整数|
|姓名:Varchar|
|反应|
|-----------------|
|id:整数|
|  |
|配料|
|-----------------------|
|物料标识:整数|
|反应id:整数|
|数量:真实|
这映射了材料和反应之间的多对多关系

我想运行一个查询,返回每一对没有形成反应的材料。(也就是说,每对(x,y)都不存在完全使用x和y的反应,也不存在其他材料。)在其他情况下,我会在中间表上进行左连接,然后查找NULL
reaction\u id
s。在本例中,我通过对materials表和它本身进行交叉连接来获得对,但我不确定如何(或是否)对两个材质别名进行两次左连接

如何做到这一点


我最感兴趣的是一种通用的SQL方法,但我目前正在使用SQLite3和SQLAlchemy。我可以选择将数据库移动到PostgreSQL,但强烈建议使用SQLite。

使用交叉连接来生成列表,然后删除处于相同反应中的对

select m.id, m2.id as id2
from materials m cross join
     materials m2
where not exists (select 1
                  from ingredient i join
                       ingredient i2
                       on i.reaction_id = i2.reaction_id and
                          i.material_id = m.id and
                          i2.material_id = m2.id
                 );
虽然这个查询看起来很复杂,但它本质上是对您的问题的直接翻译。
where
条款是说,对于同一反应,没有两种成分具有每种材料

对于性能,您需要一个关于
成分(反应id、材料id)
的索引

编辑:

如果愿意,您可以在不存在
的情况下使用
左连接
where
执行此操作:

select m.id, m2.id
from materials m cross join
     materials m2 left join
     ingredients i
     on i.material_id = m.id left join
     ingredients i2
     on i2.material_id = m2.id and
        i2.reaction_id = m2.reaction_id
where i2.reaction_id is null;