首页> 软件工程> 联合开发遇到MySQL多表关联解决办法

[文章]联合开发遇到MySQL多表关联解决办法

收藏
0 550 0


【摘要】

本次联合开发有个需求是表与表可以进行跨数据库、跨表进行关联查询,主要的关联关系有并集查询、交集查询、左关联查询、右关联查询。

【正文】

        一般我们进行SQL查询的时候基本是在同一个数据库下进行的,而本次要求可以跨数据库查询,解决办法就是将要查询的表先同步到当前的数据库下,然后再进行关联查询。但是本次的需求是理论上可以进行无上限数量的表关联查询的,所以不仅需要同步不同数据库下的表到当前的数据库下,还要编写多个查询语句,最后再进行拼接。

        解决了不同数据库的问题,就要解决多个关联的问题了。例如:有表1,表2,表33张表,表1先和表2进行并集关联,然后表3再和表1、表2并集关联后的结果进行左关联,最后得到结果。当然,这个只是一个例子,而真正的情况可能不止有3张表,还会有更多的奇怪关联。

        为了解决这个问题,我们先来看看那四种关联关系查询语句:

        1、并集查询

        SQL语句:select * from 1 as a left join 2 as b on 1.id=2.id union select * from 1 as a right join 2 as b on 1.id=2.id;

        当然,on连接的条件都是根据实际情况来的。

        2、交集查询

        SQL语句:select * from 1 as a inner join 2 as b on 1.id=2.id;

        3、左关联查询

        SQL语句:select * from 1 as a left join 2 as b on 1.id=2.id;

        4、右关联查询

        SQL语句:select * from 1 as a right join 2 as b on 1.id=2.id;

        以上就是四种关联的基本查询语句了,别名的使用需要根据实际情况来定,本次需求不仅不能使用select * 来查询,还要使用别名,因为要求最终的结果标注该字段来自哪里,例如:3张表进行关联后,返回结果中有3id,如果没有使用别名,那么我们就无法判断这些id来自哪里。

        首先,抛开字段的问题,我们来解决如何进行多张表关联查询。从上面的四种关联关系,我们可以看到如果进行多张表关联的时候,变化的是from后面的内容。当只有两张表关联的时候,from后面就是表名,当有三张表关联的时候,from后面就是上一个关联的内容。因为MySQL查询是可以使用嵌套查询的,所以有多张表关联就变成了:select * from (select * from xxx)这样的结构了。如果再多一张表也还是这样的结构,所以我们在代码里只需要进行一个判断即可。当第一次关联的时候,肯定只有两张表关联,所以from后面是表名,第二次关联的时候,from后面就是上一个关联的SQL语句了,后面依次就是上一个循环的SQL语句,按照此种逻辑就能实现循环关联了。

        循环关联解决后就要解决字段识别性的问题了。一般我们使用例如:a.id as id_xx这样的结构,这个别名也是根据实际需要进行调整的。真正重要的是要做到select *这样的效果就一定要把源表的字段和待关联表的字段全部写上,并用上别名,否则就会出现数据不一致的问题。一般第一次关联就是两张表的所有字段,第二次关联就在第一次关联的所有字段基础上加上第三张表的字段即可。但是在拼接条件的时候,(也就是on后面的条件)需要注意的是第一次关联用的还是原来的字段名称,例如:a.id=b.id,这样的形式。而在后续的关联下将会发生改变,例如:在进行第二次关联的时候,这个条件可能就变成了:a.id_xx=b.id,也就是说第二次甚至后续的关联中a后面的字段要使用别名了,不能使用原字段作为条件了,否则也会报错。

        在代码中,要解决别名的问题需要前端配合,因为我们可以从规律中看到,其实从第二次关联起,每次on后面条件发生变化的是别名a后面的字段名称,而别名b后面的字段名称还是源字段的名称。所以,前端在传递参数的时候只需要从第二次起,直接把别名写好传给我们即可。本次联合开发前端传递的结构如下:

"relation": [

        {

            "from": {

                "inst_id": 5,

                "title": "home_application_cpu"

            },

            "to": {

                "inst_id": 4,

                "title": "home_application_task"

            },

            "relate_type": "union",

            "relate": [

                {

                    "key1": {

                        "field": "id",

                        "name": "id",

                        "type": "int"

                    },

                    "key2": {

                        "field": "id",

                        "name": "id",

                        "type": "int"

                    }

                }

            ]

        },

        {

            "from": "",

            "to": {

                "inst_id": 10,

                "title": "home_application_task"

            },

            "relate_type": "left_join",

            "relate": [

                {

                    "key1": {

                        "field": "id",

                        "name": "id",

                        "type": "int",

                        "alias": "id5__home_application_cpu"

                    },

                    "key2": {

                        "field": "id",

                        "name": "id",

                        "type": "int"

                    }

                }

            ]

        },

        {

            "from": "",

            "to": {

                "inst_id": 8,

                "title": "home_application_tarresult"

            },

            "relate_type": "union",

            "relate": [

                {

                    "key1": {

                        "field": "id",

                        "name": "id",

                        "type": "int",

                        "alias": "id5__home_application_cpu"

                    },

                    "key2": {

                        "field": "id",

                        "name": "id",

                        "type": "int"

                    }

                }

            ]

        }

],

以上就是传递参数的一部分,前端使用字段alias为我们传递好了字段别名,这样我们后端就不用自己拼凑字段,也能省去很多工具代码了。

软件工程
最近热帖
{{item.Title}} {{item.ViewCount}}
近期热议
{{item.Title}} {{item.PostCount}}