Mysql 如果引用记录的其他记录链接到特定值,则从结果中排除记录
以下是我试图实现的目标: 有四个表,我必须参考,以获得我正在寻找的数据。列表、零件、列表项和标签符号Mysql 如果引用记录的其他记录链接到特定值,则从结果中排除记录,mysql,sql,Mysql,Sql,以下是我试图实现的目标: 有四个表,我必须参考,以获得我正在寻找的数据。列表、零件、列表项和标签符号 列表表具有表示每个列表的记录 listitem表引用list.id并表示每个列表上的所有项 零件表包含所有零件,每个零件都有一个唯一的id LabelAsign表具有友好的标签(如标记),其中引用partId以标记零件 视觉: 列表 id name -- ---- 1 part1 2 part2 3 part3 4 part4 id name -- ---- 1
- 列表表具有表示每个列表的记录
- listitem表引用list.id并表示每个列表上的所有项
- 零件表包含所有零件,每个零件都有一个唯一的id
- LabelAsign表具有友好的标签(如标记),其中引用partId以标记零件
id name
-- ----
1 part1
2 part2
3 part3
4 part4
id name
-- ----
1 part1
2 part2
3 part3
4 part4
10 part10
11 part11
12 part12
13 part13
14 part14
列表项
id partId listId
-- ---- ------
1 10 1
2 11 1
3 12 1
4 13 2
5 14 2
部分
id name
-- ----
1 part1
2 part2
3 part3
4 part4
id name
-- ----
1 part1
2 part2
3 part3
4 part4
10 part10
11 part11
12 part12
13 part13
14 part14
Labelassign
id label partId
-- ----- ----
1 StandardParts 1
2 StandardParts 2
3 SmallParts 3
4 LargeParts 4
5 HugeParts 5
6 MediumParts 10
7 MediumParts 11
8 MediumParts 12
9 SmallParts 13
10 MediumParts 14
要获取具有特定标签的所有列表,请执行以下操作:
SELECT list.name
FROM list
INNER JOIN part ON list.name = part.name
INNER JOIN labelassign ON part.id = labelassign.partId AND labelassign.label LIKE '%StandardParts%'
# Using LIKE for '%StandardParts%' because there are variations in the real data but I want them all
如果list.name记录没有StandardParts标签,则应将其从结果中排除
第二部分比较棘手,我遇到了麻烦
每个列表
记录都有许多列表项
记录,这些记录表示该列表上的项目。所有带有标准零件标签的列表
记录应至少有一条带有小型零件标签的列表项
记录,但并非所有有标签的记录和没有标签的记录都是我想要查找的
listitem
记录通过其listitem.listId
字段被称为属于特定列表。因此,对于每个列表
我想检查其列表项
是否有小部分作为标签(通过检查匹配的部分,以及如上所示的该部分的标签),如果这些列表项
都没有,我想在结果集中保留父列表
记录。否则,应将列表.name
从结果中排除
根据@Eric Brandt的初步回答,我目前得到的是:
SELECT DISTINCT
l.id,
l.num
FROM
list AS l
INNER JOIN
part AS p1
ON b.num = p1.num
# Without this up here I didn't get the filtration, lists without the StandardParts label were included in results
INNER JOIN
labelassign AS la
ON p1.id = la.partId
AND la.label LIKE '%StandardParts%'
INNER JOIN
listitem AS li
ON l.id = li.listId
INNER JOIN
part AS p
ON li.partId = p.id
WHERE
EXISTS
(
SELECT 1
FROM
labelassign AS la1
WHERE
la1.partId = p.id AND
la1.label LIKE '%StandardParts%'
)
AND NOT EXISTS
(
SELECT 1
FROM
labelassign AS la2
WHERE
la2.partId = p.id AND
la2.label LIKE '%SmallParts%'
);
上面仍然返回list
记录,这些记录具有listitem
记录,这些记录具有适当的SmallParts标签。同样,目标是过滤掉这些,因为我不需要修复它们。我正在查找所有list
记录,这些记录没有标签为SmallParts的listitem
记录
预期结果
id name
-- ----
1 part1
只应返回list.id 1,因为它有一个StandardParts标签,并且它的列表项没有一个小部件标签。list.id 2确实有一个StandardParts标签,但它的一个listitems有一个SmallParts标签,因此应该将其排除在外
涉及到我的问题,但主要是面向Java的,答案没有回答我的问题
我的问题再次被忽略,但实际上是一个不同的问题,即另一个表中不存在的值,而不是基于存在值的排除
如果我遗漏了一些内容,我很乐意提供更多信息。您希望对具有«SmallParts»的项目使用«left JOIN»,并使用WHERE子句筛选匹配行。您可以使用«选择不同»来避免重复。最后,我怀疑您不需要在表«part»上加入,我将其删除
SELECT DISTINCT
list.id,
list.name
FROM
list
INNER JOIN listitem ON list.id = listitem.listId
INNER JOIN labelassign l1 ON listitem.partId = l1.partId AND l1.labelId = AND l1.label LIKE '%StandardParts%'
LEFT JOIN labelassign l2 ON l2.partId = listitem.partId AND l2.label LIKE '%SmallParts%';
WHERE l2.partId IS NULL
我将尝试使用
EXISTS
子句查找具有StandardParts
标签的list.id
s,然后使用notexists
子句将这些结果限制在没有SmallParts
标签的列表中
SELECT
l.id,
l.name
FROM
list AS l
INNER JOIN
listitem AS li
ON l.id = li.listId
INNER JOIN
part AS p
ON li.partId = p.id
WHERE
EXISTS
(
SELECT 1
FROM
labelAssign AS la1
WHERE
la1.partId = p.id AND
la1.label LIKE '%StandardParts%'
)
AND NOT EXISTS
(
SELECT 1
FROM
labelAssign AS la1
WHERE
la1.partId = p.id AND
la1.label LIKE '%SmallParts%'
);
这并不是筛选出没有像“%StandardParts%”这样的零件标签的列表记录,而是返回具有与具有“SmallParts”标签的零件绑定的listitem记录的列表记录。我认为我的内部联接用法过滤不正确。@DustyArgas这应该已经可以工作了。。。我简化了查询(在«part»上不必要的连接)。然而,我发现您的测试数据中存在一个小问题,表listitem中的大多数“partId”不存在于表“part”和“labelassign”中。这是正确的,我没有发布完整的数据(从某种意义上说,我不会包括整个表,它非常大),但为了清晰起见,我添加了引用的部分”。不过我还是有额外的记录。我觉得第二个内部联接应该可以阻止我获取标签与“%StandardParts%”不同的列表记录,但事实并非如此。我还有很多。也许我误解了上一条语句的原因,但是labelassign.partId从来都不是空的。我相信你在la1.labelId=20之后缺少了一个AND(我不会编辑,因为我是mysql新手,不确定我是否正确)。与另一个答案相同,我得到了标签不是“StandardParts”的列表和标签是“Small Parts”的列表项的结果。另外,你能解释一下SELECT 1在这种情况下做了什么吗?在一个相关子查询中(这就是你在
[not]中所说的事情)EXISTS
子句,您只检查是否有任何记录符合条件。由于您不返回任何结果,您只需选择某些内容,1
是轻量级的。至于无法获得预期的结果,如果时间允许,我将再次通过您发布的更新样本数据。当我第一次查看时此时,我认为从list
到part
的关系可能很多,以listItem
作为一个桥接表。不过,现在我看到list
表中有partId
s,我根本不了解表的关系。我认为这确实需要识别匹配和不匹配sample数据,以及期望的结果,以便更清晰。好的,我编辑了这个问题,希望澄清期望的结果,以及我认为应该如何获得它。这些表比我在这里显示的要复杂得多,但我包括了相关部分,所以我删除了list.partId字段,并修改了我的初始查询以使用l使用ist.name而不是list.partId来获取匹配零件的标签。list.name应与所选零件的part.name匹配