如何连接多个表并将结果排序为类似 json 的格式

Posted

技术标签:

【中文标题】如何连接多个表并将结果排序为类似 json 的格式【英文标题】:how to join multiple tables and sort the result as a json like format 【发布时间】:2020-09-16 06:11:14 【问题描述】:

我是 mysql 的超级新手,我很确定这个问题对某些人来说可能看起来太简单了,对此我很抱歉

我有 3 个表:Portfolio、PortfolioFiles 和 PortfolioImages。表 Portfolio 与 PortfolioFiles 和 PortfolioImages 是一对多的关系

我需要做的是首先按日期获取最后 10 个投资组合的列表以及它们的文件和图像。 我试过RIGHT JOIN,它可以工作,但我面临多个问题

    当我对 OFFSETLIMIT 进行排序时,它只会获取 1 或 2 个作品集,因为某些作品集在上述表格中有多个图像和文件,所以我不知道该怎么做 当我得到结果时,它们都是行。我开始使用像 mongo 和 firebase 这样的 noSQL 数据库,所以这个 SQL 数据库对我来说看起来很神秘。因此,如果有人能指出我如何以一种无需整理获取的结果的方式进行查询,我将不胜感激

表组合

id                // primary key
uid               // foreign key reference User(id)
title
content
createdAt

表组合文件

id               // primary key
uid              // foreign key references User(id) 
portfolioId      // foreign key references Portfolio(id) 
url 
createdAt

表格组合图片

id               // primary key
uid              // foreign key references User(id)
portfolioId      // foreign key references Portfolio(id)
url
createdAt

这就是我所做的:

            SELECT 
                Portfolio.*, 
                PortfolioFiles.* , 
                PortfolioImages.* 
            FROM 
                Portfolio
            RIGHT JOIN 
                (PortfolioFiles, PortfolioImages)
            ON 
                PortfolioFiles.portfolioId=Portfolio.id 
            AND 
                PortfolioImages.portfolioId=Portfolio.id
            WHERE 
                Portfolio.uid = 49
            ORDER BY 
                Portfolio.createdAt DESC 

更新:添加样本数据

这就是我希望输出的样子:

            
                "id": 52,
                "uid": 49,
                "title": "hey this is new title",
                "content":"this is my content",
                "createdAt": "2020-09-08 17:34:23",
                "files": [
                        "id": 12,
                        "portfolioId": 52,
                        "uid": 49,
                        "url": "some random file url",
                        "createdAt": "2020-09-08 17:34:23"
                    ,
                    
                        "id": 16,
                        "portfolioId": 52,
                        "uid": 49,
                        "url": "some random file url",
                        "createdAt": "2020-09-08 17:34:23"
                    ,],
                "images": [
                    
                        "id": 44,
                        "portfolioId": 52,
                        "uid": 49,
                        "url": "some random file url",
                        "createdAt": "2020-09-08 17:34:23"
                    ,
                    
                        "id": 45,
                        "portfolioId": 52,
                        "uid": 49,
                        "url": "some random image url",
                        "createdAt": "2020-09-08 17:34:23"
                    ,
                    
                        "id": 46,
                        "portfolioId": 52,
                        "uid": 49,
                        "url": "some random file url",
                        "createdAt": "2020-09-08 17:34:23"
                    ,
                ]
            

这是当前结果:

id|uid|       title        |       content    |    createdAt     |id|pid|uid|     url           |     createdAt    |id|pid|uid|      url           |    createdAt                                                                
 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
|52|49|hey this is new title|this is my content|2020-09-08 17:34:23|12|52|49|some random file url|2020-09-08 17:34:23|12|52|49|some random image url|2020-09-08 17:34:23|    
|52|49|hey this is new title|this is my content|2020-09-08 17:34:23|12|52|49|some random file url|2020-09-08 17:34:23|12|52|49|some random image url|2020-09-08 17:34:23|
|52|49|hey this is new title|this is my content|2020-09-08 17:34:23|12|52|49|some random file url|2020-09-08 17:34:23|12|52|49|some random image url|2020-09-08 17:34:23|
|52|49|hey this is new title|this is my content|2020-09-08 17:34:23|12|52|49|some random file url|2020-09-08 17:34:23|12|52|49|some random image url|2020-09-08 17:34:23|
|52|49|hey this is new title|this is my content|2020-09-08 17:34:23|12|52|49|some random file url|2020-09-08 17:34:23|12|52|49|some random image url|2020-09-08 17:34:23|
|52|49|hey this is new title|this is my content|2020-09-08 17:34:23|12|52|49|some random file url|2020-09-08 17:34:23|12|52|49|some random image url|2020-09-08 17:34:23|
 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------

这是数据库中的数据 PortfolioImages 表

     id|portfolioId|uid|       url           |     createdAt     |
     ------------------------------------------------------------
    |44|     52    |49 |some random image url|2020-09-08 17:34:23|
    |45|     52    |49 |some random image url|2020-09-08 17:34:23|
    |46|     52    |49 |some random image url|2020-09-08 17:34:23|
     ------------------------------------------------------------

PortfolioFiles 表

     id|portfolioId|uid|       url           |     createdAt     |
     ------------------------------------------------------------
    |16|     52    |49 | some random file url|2020-09-08 17:34:23|
    |12|     52    |49 | some random file url|2020-09-08 17:34:23|
     ------------------------------------------------------------

投资组合表

      id|uid|       title        |       content    |    createdAt     
   ------------------------------------------------------------------
  |52|49|hey this is new title|this is my content|2020-09-08 17:34:23
   ------------------------------------------------------------------
            

【问题讨论】:

大多数人认为main table left join optional dataoptional data right join main table 更容易理解。 此外,您的 RIGHT JOIN 无论如何都会返回常规的 INNER JOIN 结果。将 Portfolio.uid 条件从 WHERE 移动到 ON 以获得真正的 RIGHT JOIN 结果。 你的结构是错误的。投资组合可能引用一个uid 值,而文件/图像可能引用另一个uid。从文件/图像表中删除 uid 按日期获取最后 10 个投资组合的列表以及它们的文件和图像 所有文件和图像? Anycase 显示所需的输出(对于具有 2 个文件和 2 个图像的投资组合以及没有文件或/和图像的投资组合)。 这就是我所做的 您的查询与结构相矛盾 - Portfolio 位于“一”侧,因此必须使用 LEFT JOIN。 【参考方案1】:

您尝试编写的查询是:

SELECT p.*, pf.*, pi.* 
FROM Portfolio p LEFT JOIN
     PortfolioFiles pf
     ON pf.portfolioId = p.id LEFT JOIN
     PortfolioImages pi
     ON pi.portfolioId = p.id
WHERE p.uid = 49
ORDER BY p.createdAt DESC ;

我认为这不是您真正想要的,因为这会在给定投资组合的文件和图像之间产生笛卡尔积。所以,如果有 4 个文件和 3 个图像,你会得到 12 行。嗯,实际上,你会得到 10 行带有 LIMIT 的行。

但是,您的问题不清楚实际想要什么结果。我建议你问一个新问题——但要简单一点。样本数据、所需结果以及对所需逻辑的解释就足够了。 DB Fiddle 也很受欢迎。

【讨论】:

以上是关于如何连接多个表并将结果排序为类似 json 的格式的主要内容,如果未能解决你的问题,请参考以下文章

查询行并将许多行连接为JSON数组

如何将多个 MySQLi 结果编码为正确的 json 格式?

Oracle常见的Hint

PHP MySQL连接表为JSON [重复]

如何格式化行以按第 1 列中的类似值进行颜色分组

如何对查询结果进行“计数”并将其作为 JSON 格式的数组发送?