Агрегировать без дубликатов - PullRequest
1 голос
/ 09 февраля 2020

То, что у меня здесь происходит, это:

Таблица 1: AOC_Model

AOC_ID int (Primary Key)
Model varchar(50)

Таблица 2: AOC_Chipset

AOC_CHIPSET_ID int (Primary Key)
CONTROLLER_ID int
CHIPSET_ID int
AOC_ID int

Таблица 3: Контроллер

CONTROLLER_ID int (Primary Key)
CONTROLLER varchar(10)

Таблица 4: Набор микросхем

CONTROLLER_ID int (Primary Key)
CHIPSET_ID int (Primary Key)
CHIPSET varchar(50)

Таблица 5: Notes_Chipset

NOTES_CHIPSET_ID int (Primary Key)
CONTROLLER_ID int
CHIPSET_ID int
DATE date
NOTES varchar(800)

Сначала у меня есть таблица наборов микросхем, которая присоединяется к контроллеру через Controller_ID, затем у меня есть AOC_Chipset, который фактически действует как таблица соединения между контроллером и набором микросхем. AOC_Chipset присоединяется к Chipset через Controller_ID и Chipset_id. Затем у меня есть Notes_Chipset, который также присоединяется к Chipset через Controller_ID и Chipset_id. И, наконец, у меня есть AOC_Model, который присоединяется к AOC_Chipset через AOC_ID

У меня много-много отношений происходит Вот. Я мог бы иметь один или два контроллера, назначенных на один и тот же AOC_ID. Я мог бы иметь один или два набора микросхем, назначенных одному контроллеру. У меня может быть несколько Заметок, назначенных одному и тому же Чипсету.

Я создал этот запрос в SQL Сервер 2019:

SELECT
    dbo.AOC_CHIPSET.AOC_ID, 
    string_agg(dbo.CONTROLLER.CONTROLLER, ', ') AS vControllers, 
    string_agg(dbo.CHIPSET.CHIPSET, ', ') AS vChipsets, 
    string_agg(dbo.NOTES_CHIPSET.DATE, ', ') AS vDate,
    string_agg(dbo.NOTES_CHIPSET.NOTES, ', ') AS vNotes
FROM
    dbo.AOC_CHIPSET 
INNER JOIN 
    dbo.CHIPSET ON dbo.AOC_CHIPSET.CONTROLLER_ID = dbo.CHIPSET.CONTROLLER_ID 
                AND dbo.AOC_CHIPSET.CHIPSET_ID = dbo.CHIPSET.CHIPSET_ID 
INNER JOIN 
    dbo.CONTROLLER ON dbo.CHIPSET.CONTROLLER_ID = dbo.CONTROLLER.CONTROLLER_ID 
INNER JOIN 
    dbo.NOTES_CHIPSET ON dbo.CHIPSET.CONTROLLER_ID = dbo.NOTES_CHIPSET.CONTROLLER_ID  
                      AND dbo.CHIPSET.CHIPSET_ID = dbo.NOTES_CHIPSET.CHIPSET_ID 
                      AND dbo.CONTROLLER.CONTROLLER_ID = dbo.NOTES_CHIPSET.CONTROLLER_ID
GROUP BY 
    dbo.AOC_CHIPSET.AOC_ID

Проблема в том, что результат содержит дубликаты

duplicates

Я знаю, что могу использовать DISTINCT, но я не могу понять, где / как разместить его вместе с string_agg?

Ответы [ 3 ]

0 голосов
/ 10 февраля 2020
SELECT MAX(AOC_ID) as AOC_ID, vControllers, vChipsets, vDate, vNotes FROM
(
 SELECT
    dbo.AOC_CHIPSET.AOC_ID, 
    string_agg(dbo.CONTROLLER.CONTROLLER, ', ') AS vControllers, 
    string_agg(dbo.CHIPSET.CHIPSET, ', ') AS vChipsets, 
    string_agg(dbo.NOTES_CHIPSET.DATE, ', ') AS vDate,
    string_agg(dbo.NOTES_CHIPSET.NOTES, ', ') AS vNotes
FROM
    dbo.AOC_CHIPSET 
INNER JOIN 
    dbo.CHIPSET ON dbo.AOC_CHIPSET.CONTROLLER_ID = dbo.CHIPSET.CONTROLLER_ID 
                AND dbo.AOC_CHIPSET.CHIPSET_ID = dbo.CHIPSET.CHIPSET_ID 
INNER JOIN 
    dbo.CONTROLLER ON dbo.CHIPSET.CONTROLLER_ID = dbo.CONTROLLER.CONTROLLER_ID 
INNER JOIN 
    dbo.NOTES_CHIPSET ON dbo.CHIPSET.CONTROLLER_ID = dbo.NOTES_CHIPSET.CONTROLLER_ID  
                      AND dbo.CHIPSET.CHIPSET_ID = dbo.NOTES_CHIPSET.CHIPSET_ID 
                      AND dbo.CONTROLLER.CONTROLLER_ID = dbo.NOTES_CHIPSET.CONTROLLER_ID
GROUP BY 
    dbo.AOC_CHIPSET.AOC_ID
) R
GROUP BY vControllers, vChipsets, vDate, vNotes
0 голосов
/ 10 февраля 2020

Я заменил объединения на подвыборы, помещенные непосредственно в список выбора. Это позволяет мне выбирать различные значения для каждого извлеченного свойства. Фактически, всегда есть 2 суб-выбора для каждой строки для создания. Внутренний имеет SELECT DISTINCT, а внешний - string_agg. Внутренний суб-выбор фильтрует свои строки с помощью предложения WHERE с AOC_ID, совпадающим с основным SELECT

SELECT
    ac.AOC_ID,
    (SELECT string_agg(CONTROLLER, ', ') FROM
      (SELECT DISTINCT CONTROLLER
       FROM dbo.CONTROLLER co INNER JOIN dbo.AOC_CHIPSET ac1
          ON ac1.CONTROLLER_ID = co.CONTROLLER_ID
       WHERE ac1.AOC_ID = ac.AOC_ID) x) AS vControllers,
    (SELECT string_agg(CHIPSET, ', ') FROM
      (SELECT DISTINCT CHIPSET
       FROM dbo.CHIPSET cs INNER JOIN dbo.AOC_CHIPSET ac2 
          ON ac2.CONTROLLER_ID = cs.CONTROLLER_ID AND ac2.CHIPSET_ID = cs.CHIPSET_ID
       WHERE ac2.AOC_ID = ac.AOC_ID) y) AS vChipsets,
    (SELECT string_agg([DATE], ', ') FROM
      (SELECT DISTINCT [DATE]
       FROM dbo.NOTES_CHIPSET nd INNER JOIN dbo.AOC_CHIPSET ac3
          ON ac3.CONTROLLER_ID = nd.CONTROLLER_ID AND ac3.CHIPSET_ID = nd.CHIPSET_ID
       WHERE ac3.AOC_ID = ac.AOC_ID) z) AS vDate,
    (SELECT string_agg(NOTES, ', ') FROM
      (SELECT DISTINCT NOTES
       FROM dbo.NOTES_CHIPSET nd INNER JOIN dbo.AOC_CHIPSET ac4
          ON ac4.CONTROLLER_ID = nd.CONTROLLER_ID AND ac4.CHIPSET_ID = nd.CHIPSET_ID
       WHERE ac4.AOC_ID = ac.AOC_ID) z) AS vNotes
FROM
    dbo.AOC_CHIPSET ac
GROUP BY
    ac.AOC_ID

SELECT DISTINCT в подзапросах работает, потому что список выбора не работает содержит любой идентификатор контроллера или чипсета. Это не было бы возможно с соединениями на внешнем уровне, так как те требуют этих идентификаторов.

0 голосов
/ 10 февраля 2020

Я не совсем понимаю, какова цель / использование этого запроса, так что извините, если это не поможет. Но я не думаю, что DISTINCT будет очень полезен для вас, поскольку ваш AOC_ID является уникальным значением в каждой строке дублирующихся данных. Если вы избавились от AOC_ID, вы могли бы использовать DISTINCT и не беспокоиться о том, что эти данные появляются дважды. Но опять же, если избавиться от AOC_ID в этом запросе не вариант, я такой же тупой, как и вы.

...