Как я могу запросить денормализованную таблицу и получить связанные данные в наборе результатов? - PullRequest
0 голосов
/ 31 октября 2018

У меня есть таблица, которая содержит некоторые денормализованные данные, например, следующие (подделка, чтобы упростить мой вопрос):

Книжный стол

ID, Title, Author-Name, Publisher-Name, Category

В другой таблице у меня есть что-то вроде следующего:

Таблица автора

ID, Author-Name, Address

Стол издателя

ID, Publisher-Name, Address

Предположим, что Publisher-Name и Author-Name всегда уникальны.

Требуемый набор результатов

Теперь все, что я хочу сделать, - это создать запрос, который создает набор результатов, который включает:

 1. all columns from Book table
 2. Author.ID 
 3. Publisher.ID

Окончательный набор результатов будет выглядеть примерно так:

Результирующие столбцы

ID, Title, Author-Name, Author.ID as [AuthorID], Publisher-Name, Publisher.ID as [PublisherID] Category

Допустим, в Таблице книг есть две строки, тогда результирующий набор будет иметь две строки, которые включают соответствующие значения для Author.ID и Publisher.ID, поскольку поиск был выполнен в запросе и возвращен в набор результатов.

То, что я пробовал: присоединиться

Я пытался использовать различные объединения, но всегда получаю more rows than just two rows, потому что объединение, похоже, объединяет Publisher.ID И Author.ID и I get 1 row для каждого из них, что в итоге дает мне 4 строки вместо 2.

Пример данных

Книга

1, 'All The Time', 'Fred Smith', 'Big Pub Co.', 'non-fiction'
2, 'Biggest Title Ever', 'John Jones', 'Small Pub Co.', 'fiction'

Авторы

100, 'Fred Smith', 'Yukon, AK'
101, 'John Jones', 'Happy, VT'

Издатели

300, 'Big Pub Co', 'Angry, IL'
301, 'Small Pub Co', 'Someplace, IN'

Ожидаемый набор результатов

1, 'All The Time', 'Fred Smith', 100, 'Big Pub Co.', 300, 'non-fiction'
2, 'Biggest Title Ever', 'John Jones', 101, 'Small Pub Co.' 301, 'fiction'

Ответы [ 4 ]

0 голосов
/ 31 октября 2018

Итак, несколько вещей:

  1. Ваши данные не денормализованы, они (правильно) нормализованы.
  2. Вы приняли странное решение сохранить автора имя и издателя имя в таблице книг. Это вызовет проблемы, если у вас есть два автора или издателя с одинаковым именем в соответствующих таблицах. Если это гарантированно никогда не произойдет (то есть вам потребуется вариант имени в случае авторов или издателей с одинаковыми именами), тогда вы можете избавиться от столбца ID в их соответствующих таблицах.
  3. Решение вашей проблемы - использовать JOIN, как вы вывели, но мы не можем сказать, где вы совершили ошибку, потому что вы не показали, что вы пытались .

Все это говорит о том, что вы случайно выполнили декартово JOIN, в котором вы объединяете несколько таблиц, но не можете предоставить условие соединения .

Итак, я подозреваю, что вы написали что-то вроде (есть разные способы выразить это):

FROM Books JOIN Authors JOIN Publishers

и вы должны были написать:

FROM Books INNER JOIN Authors ON Books.Author-Name = Authors.Author-Name
   INNER JOIN Publishers ON Books.Publisher-Name = Authors.Publisher-Name
0 голосов
/ 31 октября 2018

Вы можете попробовать JOIN` и получить нужные столбцы из этих таблиц.

SELECT 
    b.ID, 
    b.Title,
    b.[Author-Name],
    a.id,
    p.[Publisher-Name],
    p.id,b.Category
FROM Book b 
JOIN Author a on b.[Author-Name] = a.[Author-Name]
JOIN  Publisher p ON b.[Publisher-Name] = p.[Publisher-Name]
0 голосов
/ 31 октября 2018

Вместо Inner я бы предложил вам покинуть соединение на случай, если между таблицами не будет совпадений.

SELECT
    ...
FROM
    BookTable BOOK
    LEFT JOIN
    AuthorTable AT
        ON AT.Author-Name = BOOK.Author-Name
    LEFT JOIN
    PublisherTable PT
        ON PT.Publisher-Name = BOOK.Publisher-Name

Однако, чтобы убедиться, что ваши строки из Таблицы книг не будут умножены: используйте external apply:

SELECT
    BOOK.ID,
    BOOK.Title,
    BOOK.Author-Name,
    AT.ID AS AuthorID,
    BOOK.Publisher-Name,
    PT.ID AS PublisherID,
    BOOK.Category
FROM
    BookTable BOOK
    OUTER APPLY (SELECT TOP 1 ID FROM AuthorTable AT WHERE AT.Author-Name = BOOK.Author-Name) AT
    OUTER APPLY (SELECT TOP 1 ID FROM PublisherTable PT WHERE PT.Publisher-Name = BOOK.Publisher-Name) PT
0 голосов
/ 31 октября 2018

Из того, что я понял, я думаю, что это то, что вы хотите:

Select b.*, a.ID as author_id, p.ID as publisher_id
FROM books b
INNER JOIN Authors a
ON a.[Author-Name] = b.[Author-Name]
INNER JOIN Publishers p
ON p.[Publisher-Name] = b.[Publisher-Name]
;

Дайте мне знать, если это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...