Не могу понять, как соединить таблицы SQL вместе, чтобы создать отчет - PullRequest
0 голосов
/ 09 октября 2019

Я не могу поделиться фактическими данными компании, поэтому, пожалуйста, имейте в виду мой упрощенный пример с той же структурой.

У нас есть система, которая отслеживает пакеты в базе данных MS SQL. Каждая упаковка содержит 1-3 коробки. Все пакеты имеют как минимум одну коробку «BoxSide». Кроме того, они могут также иметь «BoxOuter» рядом с ним, и этот блок может иметь «BoxInner» внутри него. В каждом блоке есть содержимое, о котором мы храним данные.

Таким образом, всего существует пять отдельных таблиц: одна с информацией о пакете, одна для каждого блока (сторона, внешний и внутренний) и одна таблица, содержащая данные осодержание каждого. Они связаны друг с другом, как показано на следующей диаграмме:

Табличная диаграмма

Я хочу выполнить запрос, который объединит все эти данные вотчет с одной записью для каждого пакета и полями для содержимого каждого поля, оставляя неприменимые поля пустыми. Что-то вроде:

Package. *, BoxSide.Data1, Boxside.Data2, BoxOuter.Data1, BoxOuter.Data2, BoxInner.Data1, BoxInner.Data2

Для повторения:

  • Я хочу отдельную запись для каждого пакета
  • Каждый пакет имеет BoxSide
  • Пакет МОЖЕТ иметь BoxOuter
  • BoxOuter МОЖЕТ иметь BoxInner

Я пробовал различные объединения, чтобы связать эти данные вместе, но я, кажется, всегда получаю пропущенные пакеты (если у них не было определенного типа ящика) или повторяющиеся записи одного и того же пакета несколько раздля разных типов коробок. Слишком много неудачных попыток перечислить здесь.

Может кто-нибудь с некоторым SQL-фу, пожалуйста, помогите мне с запросом, который сделает это?

Ответы [ 2 ]

0 голосов
/ 09 октября 2019

Вам нужно использовать LEFT JOIN, чтобы получить каждую запись в Package независимо от того, имеет ли она соответствующие значения в других таблицах:

    SELECT P.ID, p.Time, P.Type, P.Name, P.location,
    s.ID, sc.ID, sc.Data1, sc.Data2,sc.Data3
    o.ID, oc.ID, oc.Data1, oc.Data2, oc.Data3
    i.ID, ic.ID, ic.Data1, ic.Data2, ic.Data3
    FROM Package p
    LEFT JOIN BoxSide s ON p.ID = s.PackageID
    LEFT JOIN Contents sc ON s.ID = sc.ParentID
    LEFT JOIN BoxOuter o ON p.ID = o.PackageID
    LEFT JOIN Contents oc ON o.ID = oc.ParentID
    LEFT JOIN BoxInner i ON o.ID = i.BoxOuterID
    LEFT JOIN Contents ic ON i.ID = ic.ParentID

Обратите внимание, что вам также нужно LEFT JOIN Contents таблица несколько раз, каждый раз с другим псевдонимом, чтобы связать его с каждой родительской таблицей.

0 голосов
/ 09 октября 2019

Вы пробовали применять левые соединения в BoxOuter и BoxInner? Это должно вернуть вам пакеты независимо от того, есть ли совпадения справа.

SELECT Package.*,
       bsc.Data1,
       bsc.Data2,
       boc.Data1,
       boc.Data2,
       bic.Data1,
       bic.Data2
FROM Package p
INNER JOIN BoxSide bs ON p.id = bs.packageid
LEFT JOIN BoxOuter bo ON p.id = bo.packageid
LEFT JOIN BoxInner bi ON bo.id = bi.boxouterid
INNER JOIN Contents bsc ON bs.id = bsc.parentid
INNER JOIN Contents boc ON bo.id = boc.parentid
INNER JOIN Contents bic ON bi.id = bic.parentid
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...