如何查询非规范化表并获取结果集中的关联数据?

时间:2018-10-31 12:55:20

标签: sql sql-server tsql join

我有一个表,其中包含一些非规范化数据,如下所示(为简化我的问题,这是伪造的):

书桌

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

在另一个表中,我有如下内容:

作者表

ID, Author-Name, Address

发布者表

ID, Publisher-Name, Address

假设Publisher-NameAuthor-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

假设Book Table中有两行,那么结果集将有两行,其中包括Author.ID和Publisher.ID的适当值,因为查找已在查询中完成并返回到结果集。

我尝试过的内容:加入

我尝试使用各种联接,但是我总是得到more rows than just two rows,因为联接似乎在Publisher.ID以及Author.ID和我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 :(得分:2)

您可以尝试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]

答案 1 :(得分:2)

所以,有几件事:

  1. 您的数据没有被非规范化,而是被(正确地)规范化了。
  2. 您做出了一个奇怪的决定,将作者 name 和出版者 name 存储在books表中。如果您在各自的表中有两个具有相同名称的作者或发布者,则将导致问题。如果保证这种情况永远不会发生(也就是说,对于同名作者或出版商,您需要使用名称的变体),那么您可以摆脱它们各自表中的ID列。
  3. 解决问题的方法是使用推论得出的JOIN,但由于您未显示尝试过的内容,我们无法确定您在哪里犯了错误。

总而言之,听起来您不小心执行了笛卡尔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

答案 2 :(得分:0)

据我了解,我认为这就是您想要的:

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]
;

让我知道这是否可行。

答案 3 :(得分:0)

如果您的表之间不匹配,我建议您不要使用内连接。

<option value="{key + 1}">
    <xsl:if test="value = /result/startMonthName">
        <xsl:attribute name="selected">selected</xsl:attribute>
    </xsl:if>
    <xsl:value-of select="value"/>
</option>

但是要确保您的Book Table中的行不会被相乘:请使用外部Apply:

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