如果其他引用记录的记录链接到特定值,则从结果中排除记录

时间:2018-12-26 22:05:08

标签: mysql sql

这就是我要完成的工作:

要获取所需的数据,我必须参考四个表。列表,零件,列表项和标签分配。

  • 列表表具有代表每个列表的记录
  • listitem表引用list.id并代表每个列表中的所有项目
  • 零件表包含所有零件,每个零件都有唯一的ID
  • labelassign表具有友好的标签(如标签),在其中引用了partId以便标记零件。

视觉:

列表

id  name
--  ----
1   part1
2   part2
3   part3
4   part4

列表项

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
10  part10
11  part11
12  part12
13  part13
14  part14

标签分配

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 标签,则应将它们从结果中排除。

第二部分比较棘手,遇到麻烦的地方。

每个list记录都有许多listitem记录,它们代表该列表中的项目。所有带有 StandardParts 标签的list记录应至少具有一个带有 SmallParts 标签的listitem记录,但不是所有的记录都具有,不是我想找到的。

listitem记录通过其listitem.listId字段被称为属于特定列表。因此,对于每个list,我想检查其任何listitem是否具有 SmallParts 作为标签(通过检查匹配的零件以及该零件的标签,如图所示)以上),并且如果这些listitem都没有,我是否希望将父list记录保留在结果集中。否则,应从结果中排除list.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的标签,但是其中一个列表项带有SmallParts的标签,因此应将其排除。

This question涉及了我的问题,但主要针对Java,答案未回答我的问题。

This question再次回答了我的问题,但实际上是一个不同的问题,即另一个表中不存在值,而不是根据值的存在进行排除。

如果我遗漏了一些东西,我很乐意提供更多信息。

2 个答案:

答案 0 :(得分:0)

您希望在具有«SmallParts»的项目上具有«ÂLEFTJOIN»,并带有WHERE子句以过滤出匹配的行。您可以使用«SELECT DISTINCT»来避免重复。最后,我怀疑您不需要在表«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

答案 1 :(得分:0)

我会尝试使用<ContentPresenter.Resources> <Style TargetType="TextBlock"> <Setter Property="TextTrimming" Value="CharacterEllipsis"></Setter> </Style> </ContentPresenter.Resources> 子句来查找带有EXISTS标签的list.id,然后再使用StandardParts子句将那些结果限制为没有部分的列表带有NOT EXISTS标签。

SmallParts