MySQL:没有特定列值的联接表列

MySQL:没有特定列值的联接表列,mysql,Mysql,我有一个存储文件信息的表,名为files。文件表中的每一行都可以与多个类别和标记相关 我创建了一个名为file\u relationships的表,该表存储了文件与其类别和标记之间的链接 基本上,我想做的是根据特定的类别和标签过滤我的结果 因此,例如,我可能希望提取标记号为12和15的所有文件,以及类别号为1和2的文件 但是,假设其中一个文件分配了标签号12,但没有任何类别关系。我仍然希望它被包括在结果中 我也希望没有任何标签和类别分配的文件被包括在内。我通过使用下面我的SQLFIDLE链接中的

我有一个存储文件信息的表,名为
files
文件
表中的每一行都可以与多个类别标记相关

我创建了一个名为
file\u relationships
的表,该表存储了文件与其类别和标记之间的链接

基本上,我想做的是根据特定的类别和标签过滤我的结果

因此,例如,我可能希望提取标记号为12和15的所有文件,以及类别号为1和2的文件

但是,假设其中一个文件分配了标签号12,但没有任何类别关系。我仍然希望它被包括在结果中

我也希望没有任何标签和类别分配的文件被包括在内。我通过使用下面我的SQLFIDLE链接中的
fr实现了这一点。关系为NULL

我已经创建了一个MySQL代码的快速模型。这是一个非常糟糕的代码,但希望它能帮助我理解我想要实现的目标

替换为或 --->

fr.relationship='tag'和fr.relationship_id IN('12','15')) fr.relationship='cat'和fr.relationship\u id位于('1','2'))

您正在检查fr.relationship='tag'和fr.relationship='cat' 对于1条记录/行,fr.relationship可以是“cat”或“tag” 不能同时等于这两个值

SELECT f.id,
       f.file_title ,fr.relationship
FROM files AS f
LEFT JOIN file_relationships AS fr
  ON f.id = fr.file_id
and /*REPLACEMENT as u want null column also */ (
  fr.relationship IS NULL
  OR (fr.relationship NOT IN ('tag','cat'))
  OR (
    (fr.relationship = 'tag' AND fr.relationship_id IN('12','15'))
    or (fr.relationship = 'cat' AND fr.relationship_id IN('1', '2'))
  )
)
GROUP BY f.id
EDIT---
这就是你想要的吗

替换为或 --->

fr.relationship='tag'和fr.relationship_id IN('12','15')) fr.relationship='cat'和fr.relationship\u id位于('1','2'))

您正在检查fr.relationship='tag'和fr.relationship='cat' 对于1条记录/行,fr.relationship可以是“cat”或“tag” 不能同时等于这两个值

SELECT f.id,
       f.file_title ,fr.relationship
FROM files AS f
LEFT JOIN file_relationships AS fr
  ON f.id = fr.file_id
and /*REPLACEMENT as u want null column also */ (
  fr.relationship IS NULL
  OR (fr.relationship NOT IN ('tag','cat'))
  OR (
    (fr.relationship = 'tag' AND fr.relationship_id IN('12','15'))
    or (fr.relationship = 'cat' AND fr.relationship_id IN('1', '2'))
  )
)
GROUP BY f.id
EDIT---
这就是你想要的吗


我想我有你想要的,但让我解释清楚发生了什么。我仅从文件关系表中预查询(别名PQ)每个文件ID上的聚合。这些聚合基本上是1或0的标志,表示它没有或没有任何内容

左连接的结果是,如果根本不存在任何关系,那么您需要该条目,因此您的IS NULL显然很好

现在,考虑一个没有任何“TAG”或“CAT”条目的文件。这就是HasOtherRelationship的最大值(IF())所在。通过给定文件ID的所有条目,我关心的是“除了cat或tag之外还有其他条目吗”。。。如果是,则设置为1,否则保留0。类似地,“HasTagOrCat”也有一个标志,因此在我的where子句中,我要查找其他关系=1且has标记或Cat标志为零的任何内容

最后,讨论满足标记或cat限定符考虑的要求,但如果文件有其他cat或tag条目,则不满足。类似的MAX(IF())用于这些

select
      f.id,
      f.file_title
   from
      files f
         LEFT JOIN
         ( select 
                 fr.file_id,
                 max( if( fr.relationship IN ('tag','cat'), 1, 0 )) as HasTagOrCat,
                 max( if( fr.relationship NOT IN ('tag','cat'), 1, 0 )) as HasOtherRelation,
                 max( if( fr.relationship = 'tag' AND fr.relationship_id IN('12','15'), 1, 0 )) as HasTags,
                 max( if( fr.relationship = 'cat' AND fr.relationship_id IN('1','2'), 1, 0 )) as HasCats,
                 max( if( fr.relationship = 'tag' AND fr.relationship_id NOT IN('12','15'), 1, 0 )) as HasOtherTags,
                 max( if( fr.relationship = 'cat' AND fr.relationship_id NOT IN('1','2'), 1, 0 )) as HasOtherCats
              from 
                 file_relationships AS fr
              group by
                 fr.file_id ) PQ
         ON f.id = PQ.file_id
   where
         PQ.file_id IS NULL
      OR (    PQ.HasOtherRelation = 1
          AND PQ.HasTagOrCat = 0 )
      OR (    PQ.HasTags + PQ.HasCats > 0
          AND PQ.HasOtherTags + PQ.HasOtherCats = 0 )
因此,在内部预查询结束时,您的结果将具有以下内容

File_ID  HasTagOrCat  HasOtherRelation  HasTags  HasCats  HasOtherTags  HasOtherCats
1        1            0                 1        1        0             0
2        1            0                 1        1        1             1
3        1            0                 1        0        0             0
因此,您的数据在数据样本中没有任何此类非标记/cat注意事项,关系表中没有此类文件条目也没有任何空值,但上面总结的其他注意事项将导致结果集中只包括文件1和3


它们每个都至少有一个标签或一只猫,您正在寻找一个您不想要的无其他标签/猫。对于条目2,是的,它既有一个标签,也有一个你们要找的猫,但也有其他你们没有的标签/猫,所以这被排除在结果之外。

我想我有你们要找的,但让我解释一下发生了什么。我仅从文件关系表中预查询(别名PQ)每个文件ID上的聚合。这些聚合基本上是1或0的标志,表示它没有或没有任何内容

左连接的结果是,如果根本不存在任何关系,那么您需要该条目,因此您的IS NULL显然很好

现在,考虑一个没有任何“TAG”或“CAT”条目的文件。这就是HasOtherRelationship的最大值(IF())所在。通过给定文件ID的所有条目,我关心的是“除了cat或tag之外还有其他条目吗”。。。如果是,则设置为1,否则保留0。类似地,“HasTagOrCat”也有一个标志,因此在我的where子句中,我要查找其他关系=1且has标记或Cat标志为零的任何内容

最后,讨论满足标记或cat限定符考虑的要求,但如果文件有其他cat或tag条目,则不满足。类似的MAX(IF())用于这些

select
      f.id,
      f.file_title
   from
      files f
         LEFT JOIN
         ( select 
                 fr.file_id,
                 max( if( fr.relationship IN ('tag','cat'), 1, 0 )) as HasTagOrCat,
                 max( if( fr.relationship NOT IN ('tag','cat'), 1, 0 )) as HasOtherRelation,
                 max( if( fr.relationship = 'tag' AND fr.relationship_id IN('12','15'), 1, 0 )) as HasTags,
                 max( if( fr.relationship = 'cat' AND fr.relationship_id IN('1','2'), 1, 0 )) as HasCats,
                 max( if( fr.relationship = 'tag' AND fr.relationship_id NOT IN('12','15'), 1, 0 )) as HasOtherTags,
                 max( if( fr.relationship = 'cat' AND fr.relationship_id NOT IN('1','2'), 1, 0 )) as HasOtherCats
              from 
                 file_relationships AS fr
              group by
                 fr.file_id ) PQ
         ON f.id = PQ.file_id
   where
         PQ.file_id IS NULL
      OR (    PQ.HasOtherRelation = 1
          AND PQ.HasTagOrCat = 0 )
      OR (    PQ.HasTags + PQ.HasCats > 0
          AND PQ.HasOtherTags + PQ.HasOtherCats = 0 )
因此,在内部预查询结束时,您的结果将具有以下内容

File_ID  HasTagOrCat  HasOtherRelation  HasTags  HasCats  HasOtherTags  HasOtherCats
1        1            0                 1        1        0             0
2        1            0                 1        1        1             1
3        1            0                 1        0        0             0
因此,您的数据在数据样本中没有任何此类非标记/cat注意事项,关系表中没有此类文件条目也没有任何空值,但上面总结的其他注意事项将导致结果集中只包括文件1和3


它们每个都至少有一个标签或一只猫,您正在寻找一个您不想要的无其他标签/猫。对于条目2,是的,它有一个标签和一个您正在寻找的猫,但也有其他您没有的标签/猫,所以被排除在结果之外。

您是否只需要输入一个OR而不是and?看到这个SQLfiddle:@ibizaman非常接近,但它不会给出我想要的结果。如果一个文件有标签号12和类别号3(3未被搜索),我不希望它显示出来。但是如果文件有标签号12,没有类别,那么我希望它显示出来。我说得通吗?非常感谢你的帮助!您是否只需要输入OR而不是AND?看到这个SQLfiddle:@ibizaman非常接近,但它不会给出我想要的结果。如果一个文件有标签号12和类别号3(3未被搜索),我不希望它显示出来。B