可以仅通过一个查询来处理SELECT,SELECT COUNT和交叉引用表吗?
作者:互联网
我有一个页面,显示项目列表.对于每个项目,将显示从mysqli数据库检索的以下数据:
>标题
>字幕
>说明
>零件编号(x的1)
>与该项目关联的照片总数
>从项目中随机选择的照片
>标签列表
使用分页系统,每页显示6个项目
由于这是基于我的一个旧项目,因此最初是使用许多查询通过草率的代码完成的(我只是在学习,对它的了解并不多).实际上,三个仅用于项目5-7,并且这些项目包含在与分页系统一起使用的while循环中.我现在很清楚,这甚至还远远不是做生意的正确方法.
我对INNER JOIN和子查询的使用很熟悉,但是由于以下原因,我可能无法仅使用一个选择查询来获取所有这些数据:
>使用基本的SELECT查询就可以轻松完成项目1-4,但是…
>项目5需要一个“选择计数”并…
>项6需要一个基本的SELECT查询,其ORDER by RAND LIMIT 1 to
从与每个项目相关的所有照片中选择一张随机照片
(使用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
标签:subquery,mysqli,inner-join,nested-query,php 来源: https://codeday.me/bug/20191026/1935837.html