SELECT、SELECT COUNT和交叉引用表只能由一个查询处理吗



我有一个显示项目列表的页面。每个项目都显示从mysqli数据库检索到的以下数据:

  1. 标题
  2. 副标题
  3. 说明
  4. 零件号(第1个,共x个)
  5. 与该项目关联的照片总数
  6. 从项目中随机选择的照片
  7. 标签列表

使用分页系统每页显示6个项目

由于这是基于我的一个旧项目,它最初是用草率的代码完成的(我只是在学习,不知道更多),使用了许多查询。事实上,只有第5-7项有三个,这些都包含在使用分页系统的while循环中。我现在很清楚,这甚至不是做生意的正确方式。

我熟悉INNER JOIN和子查询的使用,但我担心仅使用一个选择查询可能无法获得所有这些数据,原因如下:

  • 使用基本的SELECT查询,项目1-4就足够简单了,但是。。。

  • 项目5需要SELECT COUNTAND。。。

  • 项6需要具有ORDER by RAND LIMIT 1的基本SELECT查询从与每个项目相关的所有照片中随机选择一张(使用FilesystemIterator是不可能的,因为照片表中有一列,如果照片处于非活动状态,则指示0;如果照片处于活动状态,指示1活动)

  • 项目7是从标签和项目和一个包含标签ID和名称的表

鉴于此,我不确定这一切是否可以(甚至应该)只用一个查询完成,或者是否需要多个查询。我反复读到,在while循环中嵌套一个或多个查询值得用报纸拍鼻子。我甚至读到过,一般来说,多个查询是个坏主意。

所以我被卡住了。我意识到这听起来可能太笼统了,但我没有任何可用的代码,只有使用4个查询来完成这项工作的旧代码,其中3个嵌套在while循环中。

下面的数据库结构。

项目表:

+-------------+---------+----------+---------------+------+
| project_id  | title   | subtitle | description   | part |
|---------------------------------------------------------|
|       1     |   Chevy | Engine   | Modify        |  1   |
|       2     |   Ford  | Trans    | Rebuild       |  1   |
|       3     |   Mopar | Diff     | Swap          |  1   |
+-------------+---------+----------+---------------+------+

照片表:

+----------+------------+--------+
| photo_id | project_id | active |
|--------------------------------|
|     1    |     1      |    1   |
|     2    |     1      |    1   | 
|     3    |     1      |    1   |
|     4    |     2      |    1   |
|     5    |     2      |    1   |
|     6    |     2      |    1   |
|     7    |     3      |    1   |
|     8    |     3      |    1   |
|     9    |     3      |    1   |
+----------+------------+--------+

标签表:

+--------+------------------+
| tag_id |        tag       |
|---------------------------|
|    1   | classic          |
|    2   | new car          |
|    3   | truck            |
|    4   | performance      |
|    5   | easy             |
|    6   | difficult        |
|    7   | hard             |
|    8   | oem              |
|    9   | aftermarket      |
+--------+------------------+

标签/项目对照表:

+------------+-----------+
| project_id | tag_id    |
|------------------------|
|      1     |     1     |
|      1     |     3     |
|      1     |     4     |
|      2     |     2     |
|      2     |     5     |
|      3     |     6     |
|      3     |     9     |
+------------+-----------+

我并不是要求为我编写代码,但如果我的要求有意义,我真诚地希望能朝着正确的方向前进。我经常在网上纠结于PHP和MySQLi手册,所以如果有什么方法可以解决这个问题,那就太棒了。

非常感谢大家。

您可以在SELECT子句中执行子查询,如下所示:

SELECT 
p.title, p.subtitle, p.description, p.part,
(SELECT COUNT(photo_id) FROM Photos where project_id = p.project_id) as total_photos, 
(SELECT photo_id FROM Photos where project_id = p.project_id ORDER BY RAND LIMIT 1) as random_photo
FROM projects as p

现在,对于标记列表,因为它返回多行,所以不能执行子查询,而应该为每个项目执行一个查询。事实上,如果你以某种串联的方式返回所有标签,比如逗号分隔的列表:tag1、tag2、tag3……但我不建议你需要分解列值。只有当您有许多项目,并且检索每个项目的标记列表的性能相当低时,才能执行此操作。如果你真的想,你可以:

SELECT 
p.title, p.subtitle, p.description, p.part,
(SELECT COUNT(photo_id) FROM Photos where project_id = p.project_id) as total_photos, 
(SELECT photo_id FROM Photos where project_id = p.project_id ORDER BY RAND LIMIT 1) as random_photo,
(SELECT GROUP_CONCAT(tag SEPARATOR ', ') FROM tags WHERE tag_id in (SELECT tag_id FROM tagproject WHERE project_id = p.project_id)) as tags
FROM projects as p

正如您在第1项到第4项中所说,您已经有了解决方案。

SQL_CALC_FOUND_ROWS而不是SELECT COUNT添加到同一查询中以解决项目5。

对于第6项,您可以使用子查询,也可以使用限制为一个结果的LEFT JOIN

对于最新的项目,您还可以使用子查询将所有标记连接到一个结果中(例如,用逗号分隔)。

相关内容

  • 没有找到相关文章

最新更新