Исключить записи из результатов, если другие записи, ссылающиеся на них, связаны с определенным значением - PullRequest
0 голосов
/ 27 декабря 2018

Вот что я пытаюсь сделать:

Есть четыре таблицы, на которые я должен ссылаться, чтобы получить данные, которые я ищу.list, part, listitem и labelassign.

  • Таблица списка содержит записи, представляющие каждый список
  • Таблица listitem ссылается на list.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

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 , они должны быть исключены из результатов.

Вторая часть более сложная, и у меня возникают проблемы.

Каждая запись list имеетколичество listitem записей, которые представляют элементы в этом списке.Все list записи, имеющие метку StandardParts , должны иметь хотя бы одну запись listitem с меткой SmallParts , но не все делают, а те, которые не являются тем, что яхочу найти.

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 записи, которые не имеют listitem записи с меткой SmallParts .

Ожидаемые результаты

id  name
--  ----
1   part1

Должен быть возвращен только list.id 1, так как он имеет метку StandardParts и ни один из его элементов списка не имеет метки мелких деталей.list.id 2 имеет метку StandardParts, но один из его элементов списка имеет метку SmallParts, поэтому ее следует исключить.

Этот вопрос касается моегопроблема, но в основном ориентирована на Java, и ответы не отвечают на мой вопрос.

Этот вопрос снова решает мою проблему, но на самом деле это другая проблема, проблема несуществующего значения в другомтаблица, а не исключение, основанное на наличии значения.

Я с удовольствием предоставлю больше информации, если что-то пропущу.

Ответы [ 2 ]

0 голосов
/ 27 декабря 2018

Я бы попробовал предложение EXISTS, чтобы найти list.id с меткой StandardParts, а затем предложение NOT EXISTS, чтобы ограничить эти результаты списками, в которых ни одна деталь не имеет метки 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%'
    );
0 голосов
/ 27 декабря 2018

Требуется «LEFT JOIN» для элементов, имеющих «SmallParts», с предложением 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...