SQL多表查询、跨服务器查询

怎样联合查询这几个表并进行计算呢,而且还存在数据在不同服务器中,A、B、C、D在服务器①,E、F表在服务器②,这种情况还可以查询吗。

输入
A表

时间评分
2022-100
2022-111
2022-122

B表

时间评分
2022-1010
2022-106
2022-1110

C表

时间编号评分
2022-10-11 00:00:00A000111
2022-10-11 01:00:00A000212
2022-11-20 13:00:00A000313

D表

时间编号评分
2022-10-13 00:00:00SSN512066520
2022-10-14 01:00:00SSN512066620
2022-11-25 13:00:00SSN512066723
2022-10-14 23:00:00C22042412
2022-10-12 03:00:00C22042513
2022-11-27 16:00:00C22042614
2022-11-23 14:00:00N320045822
2022-10-15 19:00:00N320045923
2022-11-02 05:00:00N320045024

E表

编号子编号
SSN5120665A0001
SSN5120666A0002
SSN5120667A0003
E表与C表相匹配

F表

编号子编号
SSN5120665C220424
SSN5120665N3200458
SSN5120666C220425
SSN5120666N3200459
SSN5120667C220426
SSN5120667N3200450
F表与D表相匹配

输出

时间编号评分A评分B评分C评分D
2022-10-13SSN5120665081118
2022-10-14SSN5120666081218.66
2022-11-25SSN51206671101320.33

1、评分A根据D表时间(年月日)匹配A表对应月份,如(D表.时间=2022-10-11,输出A表.时间=2022-10的评分)
2、评分B根据D表时间(年月日)匹配B表对应月份计算平均分数,如(D表.时间=2022-10-11,输出B表.时间=2022-10的平均评分)
3、评分C根据D表编号匹配C表、E表
4、评分D根据D表编号与F表匹配计算平均分数

mysql你装了FEDERATED存储引擎了嘛?没装的话啥也做不到

你这个需求有问题啊,A表的时候是年月,D表的时间是 年月日时分秒,这个怎么匹配?匹配到多个又该怎么样?这些你都没说清楚。

数据不在同一个服务器的话,没法关联查询,那么一种办法是将数据全部用程序查出来,然后程序去匹配计算。当然这种情况仅限于数据量不大的情况。
或者如果可以将相关表同步到同一个库里,然后直接SQL关联查询就可以了。

引用chatgpt内容作答:
要实现跨服务器的多表查询和计算,你需要使用数据库联接(JOIN)操作,同时考虑到表在不同服务器上的情况,你还需要跨服务器查询的能力。

首先,假设你在服务器①执行查询,需要从服务器①上的表 A、B、C、D 中获取数据,并从服务器②上的表 E、F 中获取数据。然后根据你的描述,根据时间和编号进行匹配和计算。下面是一个基本的 SQL 查询的示例,你可以根据自己的实际情况进行调整:

SELECT
    D.time AS 时间,
    D.number AS 编号,
    A.score AS 评分A,
    AVG(B.score) AS 评分B,
    C.score AS 评分C,
    AVG(F.score) AS 评分D
FROM
    Server1.D AS D
    LEFT JOIN Server1.A AS A ON D.time = A.time
    LEFT JOIN Server1.C AS C ON D.number = C.number
    LEFT JOIN Server2.E AS E ON D.number = E.number
    LEFT JOIN Server1.B AS B ON D.time = B.time
    LEFT JOIN Server2.F AS F ON D.number = F.number
GROUP BY
    D.time, D.number, A.score, C.score
ORDER BY
    D.time;

在这个查询中,我们假设 D 表位于 Server1 上,而 A、B、C 表也位于 Server1 上,E、F 表位于 Server2 上。我们使用了 LEFT JOIN 进行连接操作,并根据时间和编号进行匹配。对于评分B和评分D,使用了 AVG() 函数来计算平均分数。最后,使用 GROUP BY 对结果进行分组,确保每个时间和编号的组合只有一行。

需要注意的是,跨服务器查询需要数据库系统支持跨服务器连接。一些数据库管理系统(例如 MySQL)支持 Federated 存储引擎,允许你在一个数据库服务器上访问另一个服务器上的表。你需要确保数据库服务器的设置和权限正确配置,以便进行跨服务器查询。

另外,为了实现你的需求,还需要根据实际情况调整表名、列名和连接条件。最好根据你使用的数据库系统的文档进行操作,因为不同的数据库系统可能在语法和设置方面有所不同。


SELECT
    D.时间,
    D.编号,
    IFNULL(A.评分, 0) AS 评分A,
    (B.评分 + C.评分) / 2 AS 评分B,
    C.评分 AS 评分C,
    (D.评分 + F.评分) / 2 AS 评分D
FROM
    D
JOIN
    (SELECT 子编号, MAX(评分) AS 评分 FROM E GROUP BY 子编号) E
ON
    D.编号 = E.子编号
JOIN
    (SELECT 子编号, AVG(评分) AS 评分 FROM F GROUP BY 子编号) F
ON
    D.编号 = F.子编号
LEFT JOIN
    A
ON
    D.时间 = A.时间
LEFT JOIN
    B
ON
    D.时间 = B.时间
LEFT JOIN
    C
ON
    D.编号 = C.编号

-- 在服务器①上执行联合查询
USE DATABASE1;
SELECT D.时间, D.编号, A.评分 AS 评分A, B.评分 AS 评分B, C.评分 AS 评分C, D.评分 AS 评分D
FROM A
JOIN B ON A.时间 = B.时间
JOIN (
    SELECT C.时间, C.编号, C.评分
    FROM C
    JOIN (
        SELECT E.子编号, E.编号
        FROM E
        JOIN (
            SELECT F.子编号, F.编号
            FROM F
            JOIN D ON F.编号 = D.编号
        ) AS F_D ON E.子编号 = F_D.子编号
    ) AS E_F ON C.编号 = E_F.编号
) AS C_E ON D.时间 = C_E.时间 AND D.编号 = C_E.编号
JOIN D ON C_E.编号 = D.编号;

-- 在服务器②上执行联合查询
USE DATABASE2;
...(根据您的需求,可能需要进一步的操作)


import psycopg2  # 示例使用PostgreSQL数据库连接库
# 创建数据库连接
conn1 = psycopg2.connect("host=server1 dbname=mydatabase user=myuser password=mypassword")
conn2 = psycopg2.connect("host=server2 dbname=mydatabase user=myuser password=mypassword")
# 创建数据库游标
cur1 = conn1.cursor()
cur2 = conn2.cursor()
# 联合查询A、B、C、D表
query = """
    SELECT D."时间", D."编号", A."评分" AS "评分A", AVG(B."评分") AS "评分B", C."评分" AS "评分C"
    FROM D
    LEFT JOIN A ON D."时间" = A."时间"
    LEFT JOIN B ON D."时间" = B."时间"
    LEFT JOIN C ON D."编号" = C."编号"
    LEFT JOIN E ON C."编号" = E."子编号"
    GROUP BY D."时间", D."编号", A."评分", C."评分"
"""
cur1.execute(query)
# 提取查询结果
results = cur1.fetchall()
# 计算评分D
for row in results:
    d_time = row[0]
    d_num = row[1]
    # 查询F表并计算评分D
    f_query = f"""
        SELECT AVG(f."评分")
        FROM F
        WHERE f."编号" = '{d_num}'
    """
    cur2.execute(f_query)
    f_avg = cur2.fetchone()
    # 将评分D添加到结果集
    row += f_avg
# 格式化和输出结果
for row in results:
    print(row)
# 关闭数据库连接
cur1.close()
cur2.close()
conn1.close()
conn2.close()


试试

-- 联合查询A、B、C、D、E、F六个表,并进行计算
SELECT 
    D.时间,
    D.编号,
    A.评分 AS 评分A,
    B.平均评分 AS 评分B,
    C.评分 AS 评分C,
    F.平均评分D AS 评分D
FROM
    (SELECT 时间, AVG(评分) AS 平均评分 FROM server1.B GROUP BY 时间) AS B
    JOIN
    (SELECT DATE_FORMAT(时间, '%Y-%m') AS 年月 FROM server1.D) AS D
    ON B.时间 = D.年月
    JOIN
    server1.A
    ON A.时间 = D.年月
    JOIN
    (SELECT D.*, C.评分 AS 评分C FROM server1.D JOIN (SELECT C.* FROM server1.C JOIN server2.E ON C.编号 = E.子编号) AS C ON D.编号 = C.编号) AS C
    ON D.编号 = C.编号
    JOIN
    (SELECT F.编号, AVG(D.评分) AS 平均评分D FROM server2.F JOIN server1.D ON F.子编号 = D.编号 GROUP BY F.编号) AS F
    ON D.编号 = F.编号;


SQL跨数据库服务器查询和跨表更新的操作
可以参考下

sql 跨服务器查询

--1.建立連接
EXEC sp_addlinkedserver
@server='DB_Name',   --链接服务器别名
@srvproduct='',
@provider='SQLOLEDB',
@datasrc=''  --要访问的的数据库所在的服务器的ip
GO
 
--2.登录
EXEC sp_addlinkedsrvlogin
'DB_Name',               --链接服务器别名
'false',                 --以SQL认证的方式登录
 NULL,
'hlaccount',                    --要访问的数据库的用户
'Q1qaz2wsx'                   --要访问的数据库用户的密码
GO
 
--3.查询
SELECT * FROM [DB_Name].数据库.架构.表名

你这个啊,涉及到多表联合查询和跨服务器查询,在数据库中可以使用 JOIN 语句进行多表查询,但跨服务器查询,可以使用临时表来实现

【以下回答由 GPT 生成】

问题优化:

根据问题描述,我理解您需要执行跨服务器的SQL多表查询和计算。具体而言,您希望联合查询A、B、C、D表,并根据一些条件进行计算。其中,A、B、C、D表位于服务器1上,而E、F表位于服务器2上。

以下是我推荐的解决方案:

  1. 创建数据库连接:
  2. 使用适当的编程语言(例如Python)创建两个数据库连接:一个用于连接服务器1,另一个用于连接服务器2。
  3. 配置连接参数以确保成功连接至各自的服务器和数据库。

  4. 联合查询A、B、C、D表:

  5. 使用连接到服务器1的数据库连接执行联合查询。
  6. 使用SELECT语句联合A、B、C、D表,根据时间和编号进行匹配。
  7. 为避免重复行,可以使用INNER JOIN或者LEFT JOIN等适当的操作符。
  8. 检索所需字段(时间、编号、评分A、评分B、评分C)。

  9. 计算评分A:

  10. 使用D表中的时间匹配A表的评分。
  11. 将结果添加到查询的结果集中。

  12. 计算评分B:

  13. 使用D表中的时间匹配B表的评分。
  14. 根据匹配的评分计算平均值。
  15. 将结果添加到查询的结果集中。

  16. 匹配C表和E表,计算评分C:

  17. 使用D表中的编号匹配C表和E表。
  18. 将C表中的评分和E表中的子编号添加到查询的结果集中。

  19. 匹配F表,计算评分D:

  20. 使用D表中的编号匹配F表。
  21. 根据匹配的评分计算平均值。
  22. 将结果添加到查询的结果集中。

  23. 格式化和输出结果:

  24. 将查询结果按要求的格式化输出。
  25. 可以使用编程语言中的数据结构和字符串操作来格式化输出。
  26. 输出结果表格,包括时间、编号、评分A、评分B、评分C、评分D。

以下是一种可能的Python解决方案的伪代码示例:

import psycopg2  # 示例使用PostgreSQL数据库连接库

# 创建数据库连接
conn1 = psycopg2.connect("host=server1 dbname=mydatabase user=myuser password=mypassword")
conn2 = psycopg2.connect("host=server2 dbname=mydatabase user=myuser password=mypassword")

# 创建数据库游标
cur1 = conn1.cursor()
cur2 = conn2.cursor()

# 联合查询A、B、C、D表
query = """
    SELECT D."时间", D."编号", A."评分" AS "评分A", AVG(B."评分") AS "评分B", C."评分" AS "评分C"
    FROM D
    LEFT JOIN A ON D."时间" = A."时间"
    LEFT JOIN B ON D."时间" = B."时间"
    LEFT JOIN C ON D."编号" = C."编号"
    LEFT JOIN E ON C."编号" = E."子编号"
    GROUP BY D."时间", D."编号", A."评分", C."评分"
"""
cur1.execute(query)

# 提取查询结果
results = cur1.fetchall()

# 计算评分D
for row in results:
    d_time = row[0]
    d_num = row[1]

    # 查询F表并计算评分D
    f_query = f"""
        SELECT AVG(f."评分")
        FROM F
        WHERE f."编号" = '{d_num}'
    """
    cur2.execute(f_query)
    f_avg = cur2.fetchone()

    # 将评分D添加到结果集
    row += f_avg

# 格式化和输出结果
for row in results:
    print(row)

# 关闭数据库连接
cur1.close()
cur2.close()
conn1.close()
conn2.close()

请注意,您可能需要根据您使用的数据库类型和编程语言进行适当的调整和修改。此示例假设您使用的是PostgreSQL数据库和Python编程语言。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

可以考虑两种方式:
1、两个数据库如果可以互相访问,那么可以进行关联查询找出所需要的结果,通过时间,编码进行关联。
2、如果数据库不能互相访问,可以先访问一个数据库,先找出能够查出的字段,然后在去查询另一个数据库。

建议通过代码层面进行分别查询,然后再去组合。
最好的方式能够定时同步到同一个数据库然后进行查询,类似于数据仓储的功能

有个分库分表工具可以用吧

AIGC 办公自动化案例实战
http://t.csdn.cn/zBytu

表的时间没有统一

要进行跨服务器的多表联合查询,用MySQL的Federated存储引擎或者使用连接其他服务器的功能

跨服务器确实不能做联合的,现在有微服务程序可以实现跨ip查询信息,你这个需求可以拆解的