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