【问题标题】:How to join multiple tables related by other tables如何连接由其他表相关的多个表
【发布时间】:2011-11-27 04:47:11
【问题描述】:

我正在开发一个网站,人们可以在该网站上发布他们的房屋出租信息。我正在使用 php 5.2.0 和 MySQL 5+

出版物存储在这样的表中

ta_publications
+---+-------------+------+
|id |    name     | date |
+---+-------------+------+
| 1 | name_001    |  ... |
| 2 | name_002    |  ... |
| 3 | name_003    |  ... |
+---+-------------+------+

我有不同的出版物,有“互联网”、“制造服务”、“卫星电视”等“特色”。

这些功能将来可能会改变,我希望能够添加/删除/修改它们,所以我将它们存储在数据库中的一个表中。

ta_features
+---+-------------+
|id | name        |
+---+-------------+
| 1 | Internet    |
| 2 | Wi-Fi       |
| 3 | satelital tv|
+---+-------------+

与使用下表的出版物相关

ta_publication_features
+---+-------------+----------------+
|id |   type_id   | publication_id |
+---+-------------+----------------+
| 1 |      1      |       1        |
| 2 |      2      |       1        |
| 3 |      3      |       1        |
+---+-------------+----------------+

我认为这很容易理解;有一个名为 name_001 的出版物,它有互联网、无线网络和卫星电视。

我有相同的图像数据架构,我将它们存储在这个表中

ta_images
+---+-------------+
|id | src         |
+---+-------------+
| 1 | URL_1       |
| 2 | URL_2       |
| 3 | URL_3       |
+---+-------------+

并使用下表将它们与出版物联系起来

ta_publication_images
+---+-------------+----------------+----------+
|id |  img_id     | publication_id |   order  |
+---+-------------+----------------+----------+
| 1 |      1      |       1        |    0     |
| 2 |      2      |       1        |    1     |
| 3 |      3      |       1        |    2     |
+---+-------------+----------------+----------+

列顺序给出了列出单个出版物时应显示的出版物的顺序。

Philipp Reichart 向我提供了一个查询,该查询将搜索并获取所有具有特定功能的出版物。它适用于列出出版物,我无法修改它以返回我需要的数据。

所以我想我将运行该查询并获取所有通过搜索条件的出版物,然后使用另一个查询列出它们。

这些出版物的列表应包括所有出版物数据(ta_publications 上的所有内容)+ 它的所有功能 + 最重要的(0 阶)图像 src。

对于每个出版物,我可以有两个简单的查询,它们将分别返回最重要的图像及其所有功能,但是当每页列出 25 个出版物时,它将是 1 个搜索查询 +(2 个查询每个出版物 * 25 个出版物)= 51 个不同的查询,显然效率不高。

编辑:

我的问题是,我如何创建一个 SQL 查询,给定一些发布 ID,它将返回:所有发布数据(ta_publications 上的所有内容)+ 它的所有功能 + 最重要的(0 阶)图像 src

【问题讨论】:

  • 写得很好,因为你是新手。 :) +投票
  • 您实际上还没有问过问题。展示你想要达到的目标。
  • 那么您是否要求查询返回所有出版物(按 ID),包括它们的特征和顶部图片?
  • 莱克:谢谢!吉姆:我想这不是很清楚,我重新提出了这个问题。迈克:是的。我把问题分成两部分。在给定 ID 列表(使用第一部分中的 id)的情况下,查找与搜索条件匹配的出版物的 ID(完成)和另一个以选择所有出版物数据、它们的所有特征和顶部 img

标签: php mysql sql database database-design


【解决方案1】:

你会用这个得到多余的出版物和图像数据,但这里有一种方法可以用一个查询来做到这一点:

   SELECT p.id, p.name, p.date,
           f.id, f.name,
           i.id, i.src
    FROM ta_publications p
    JOIN ta_publication_features pf ON p.id = pf.publication_id
    JOIN ta_features f ON f.id = pf.type_id
    JOIN ta_publication_images pi ON p.id = pi.publication_id 
         AND pi.order = 0
    JOIN ta_images i ON i.id = pi.img_id
    WHERE p.id IN (  -- list of publication ids );

【讨论】:

  • 它可以工作,但会提供冗余数据,就像你说的那样。有没有办法避免获取这些冗余数据?
  • 鉴于关系的性质,无法绕过它。
  • 什么更好,性能方面,使用搜索查询获取可能的 ID,然后使用您的查询获取列表信息,使用 PHP 删除冗余,或使用搜索查询然后对于每个出版物,进行 1 次查询以获取 IMG 并进行第二次查询以获取所有功能的列表?第二个选项更简单,更可预测,但使用了很多查询。我认为使用第二个选项进行分页会更容易。你怎么看?
  • 我的建议是两者都试一下,看看哪个效果更好!直观地说,我认为多个查询可能会更快一些,因为它只有 2n 个查询,有时加入一长串表可能会执行缓慢 - 尽管这将取决于我没有那么多经验的索引和 dbms 细节。不过,微小的性能提升(如果有的话)可能对您来说并不值得。
【解决方案2】:
 Select pub.Name as [Publication], f.name as [Feature], i.name as [Image] from ta_publications pub
Join ta_publications_features pf on pf.publication_id = pub.id
Join ta_features f on f.id = pf.type_id
Join ta_publication_images pi on pi.publication_id = pub.id
Join ta_images i on i.id = pi.img_id
Where pub.id = 'appropriate id'
order by i.[order]

如果我正确地遵循了您的结构,这应该会为您提供所需的连接。并且您可以通过添加 .. 将所需列添加到 select 语句中的结果中。希望这会有所帮助。

【讨论】:

  • 如果你想要所有的出版物,你可以取出(其中 pub.id = '适当的 id'),因为你想要顶部的 img,只需用 whith 替换顺序(其中 i.order = 0)
  • 对于一个有 6 个功能和 3 个图片的出版物,它会抛出 18 行。每张图片有 6 行,每行都有不同的特征。
  • 添加 pi.order = 0 有助于解决一些问题,它现在为每个特征返回一行。
  • 好的,我现在明白了,您需要将所有功能作为每个出版物同一行的一部分。我相信您需要加入特定出版物的所有功能的数据透视表。可能有更简单的方法,但让我看看是否可以为您整理一些语法。
  • 我查看了我之前所说的内容,我认为这有点超出我的想象。但我考虑了一下,如果您将结果集拉到应用程序或 Web 服务中,您可以在那里解析数据。我相信这会更容易和更清洁。抱歉,我在查询中找不到如何做这一切,但如果是我,我会这样做。
猜你喜欢
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
  • 2017-02-08
  • 2012-06-26
相关资源
最近更新 更多