MySQL 子查询或加入数据库名称在主查询结果集中的不同数据库
MySQL subquery or join different databases where database name is in the main query's result set
例如,我需要列出所有客户并在这个简化的自我解释中计算他们的用户 SQL:
SELECT customer_name,
(SELECT COUNT(*) FROM <main_db.customers.database_name>.users) AS user_count
FROM main_db.customers
假设这是 main_db 结构:
+--------------------------------+
| customer_name | database_name |
|--------------------------------|
| Customer One | customer_db1 |
| Customer Two | customer_db2 |
| Customer Three | customer_db3 |
| etc... |
+--------------------------------+
这是customer_dbX结构:
+------------+
| users |
|------------|
| User One |
| User Two |
| User Three |
| etc... |
+------------+
我想收到这个结果集:
+-----------------------------+
| customer_name | user_count |
|-----------------------------|
| Customer One | 12 |
| Customer Two | 59 |
| Customer Three | 34 |
| etc... |
+-----------------------------+
子查询、连接或任何语法是否可行?
如果我正确理解了你的问题,我会使用 UNION
:
SELECT CUSTOMER_NAME FROM MAIN_DB.CUSTOMERS ORDER BY ID ASC
UNION
SELECT COUNT(*) FROM MAIN_DB.CUSTOMERS.USERS GROUP BY CUSTOMERS ORDER BY ID ASC
评论太长了。
不,您不能将您想要的作为单个查询。您可以使用动态 sql 利用 information_schema.schemata
table.
但是,也许还有其他解决方案。首先,我建议您不要为不同的客户使用单独的数据库,除非您绝对必须这样做。以下是您 必须 的几个原因:
- 根据合同,您有义务使用单独的数据库(可能是因为律师不完全了解数据库安全性)。
- 数据库有不同的 backup/restore 要求。
- 不同的客户将具有客户特定的定制,这些定制最容易作为不同的数据库处理。
在大多数情况下,将多个客户的数据存储在一个数据库中是正确的做法。它无疑简化了系统管理、升级到新版本、识别和修复错误、备份数据库、在出现故障时复制系统等等。
但是,如果您必须拥有单独的数据库,则考虑在 master 数据库中创建一个将所有 table 组合在一起的视图:
create view v_master_users as
select 'x' as which, d.* from customer_db<X> d union all
select 'x1' as which, d.* from customer_db<x> d union all
. . .;
然后,使用此视图进行查询。
如果添加客户需要创建数据库,那么您将有足够的机会更新视图以处理新客户。
例如,我需要列出所有客户并在这个简化的自我解释中计算他们的用户 SQL:
SELECT customer_name,
(SELECT COUNT(*) FROM <main_db.customers.database_name>.users) AS user_count
FROM main_db.customers
假设这是 main_db 结构:
+--------------------------------+
| customer_name | database_name |
|--------------------------------|
| Customer One | customer_db1 |
| Customer Two | customer_db2 |
| Customer Three | customer_db3 |
| etc... |
+--------------------------------+
这是customer_dbX结构:
+------------+
| users |
|------------|
| User One |
| User Two |
| User Three |
| etc... |
+------------+
我想收到这个结果集:
+-----------------------------+
| customer_name | user_count |
|-----------------------------|
| Customer One | 12 |
| Customer Two | 59 |
| Customer Three | 34 |
| etc... |
+-----------------------------+
子查询、连接或任何语法是否可行?
如果我正确理解了你的问题,我会使用 UNION
:
SELECT CUSTOMER_NAME FROM MAIN_DB.CUSTOMERS ORDER BY ID ASC
UNION
SELECT COUNT(*) FROM MAIN_DB.CUSTOMERS.USERS GROUP BY CUSTOMERS ORDER BY ID ASC
评论太长了。
不,您不能将您想要的作为单个查询。您可以使用动态 sql 利用 information_schema.schemata
table.
但是,也许还有其他解决方案。首先,我建议您不要为不同的客户使用单独的数据库,除非您绝对必须这样做。以下是您 必须 的几个原因:
- 根据合同,您有义务使用单独的数据库(可能是因为律师不完全了解数据库安全性)。
- 数据库有不同的 backup/restore 要求。
- 不同的客户将具有客户特定的定制,这些定制最容易作为不同的数据库处理。
在大多数情况下,将多个客户的数据存储在一个数据库中是正确的做法。它无疑简化了系统管理、升级到新版本、识别和修复错误、备份数据库、在出现故障时复制系统等等。
但是,如果您必须拥有单独的数据库,则考虑在 master 数据库中创建一个将所有 table 组合在一起的视图:
create view v_master_users as
select 'x' as which, d.* from customer_db<X> d union all
select 'x1' as which, d.* from customer_db<x> d union all
. . .;
然后,使用此视图进行查询。
如果添加客户需要创建数据库,那么您将有足够的机会更新视图以处理新客户。