mysql - 如何使用 MySQL `SELECT FROM` 作为查询本身的一部分的表?
问题描述
假设我有多个具有相同架构的表:
CREATE TABLE `tbl01`
(
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`name` TINYTEXT,
`data` INT
);
CREATE TABLE `tbl02`
(
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`name` TINYTEXT,
`data` INT
);
CREATE TABLE `tbl03`
(
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`name` TINYTEXT,
`data` INT
);
-- etc. ------------------
INSERT INTO `tbl01` (`name`, `data`) VALUES
('row 1', 1),
('row 2', 1),
('row 3', 3);
INSERT INTO `tbl02` (`name`, `data`) VALUES
('cube', 1),
('circle', 0);
INSERT INTO `tbl03` (`name`, `data`) VALUES
('one', 1);
然后是一个表,其中一列中包含所有其他表的名称:
CREATE TABLE `AllTbls`
(
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`tblnm` VARCHAR(64) NOT NULL UNIQUE,
`desc` TINYTEXT,
`flgs` BIGINT UNSIGNED
);
INSERT INTO `AllTbls` (`tblnm`, `desc`, `flgs`) VALUES
('tbl01', 'Table 1', 0),
('tbl02', 'Table two', 1),
('tbl03', '3rd table', 0);
因此,如果我想编写一个查询来检索其中的内容AllTbls
并在一列中包含每个相应表中的行数,我认为以下方法是这样做的:
SELECT *, `tblnm` as TblName, (SELECT COUNT(*) FROM TblName) as cntRws
FROM `AllTbls` ORDER BY `id` ASC LIMIT 0,30;
但这会返回一个错误:
#1146 - 表 'database.TblName' 不存在
我知道我可以在多个查询中执行此操作(使用编程语言中的循环),但是可以在一个查询中执行此操作吗?
PS。我在用着MySQL v.5.7.28
解决方案
简单的答案是:“你不能”
表名不应该像变量一样使用,以这种方式保存数据。你应该有一张桌子:
tblContractCounts
Client, ContractCount
-------------------
IBM, 1
Microsoft, 3
Google, 2
不是三个表:
tblIBMContractCounts
ContractCount
1
tblMicrosoftContractCounts
ContractCount
3
tblGoogleContractCounts
ContractCount
2
如果您的表的数量是已知的并且是固定的,您也许可以通过创建一个将它们重新组合在一起的视图来解决问题,或者着手将它们全部放入一个表中,使用单独的视图命名为旧名称,这样事情就可以继续工作直到你可以改变它们。如果一直添加新表,则说明数据建模存在缺陷,需要进行更正。在这种情况下,您必须使用编程语言(前端或存储过程)来构建单个查询:
//pseudo code
strSql = ""
for each row in dbquery("Select name from alltbls")
strSql += "select '" + row.name + "' as tbl, count(*) as ct from " + row.name + " union all "
next row
strSql += "select 'dummy', 0"
result = dbquery(strSql)
不一定非要由您的前端来执行此操作——您也可以在 mysql 中执行此操作并利用动态 sql/EXECUTE。请参阅THIS ANSWER我们如何使用上述逻辑连接字符串,以便字符串包含 sql 查询,然后执行查询。信息模式将为您提供获取所有当前表名列表所需的信息
但是您所做的只是解决您的数据建模已损坏的事实;我建议改为修复它
ps:INFORMATION_SCHEMA 对带有名称的表进行了粗略的计数,在这种特殊情况下,这可能足以满足您的需求
select table_name, table_rows from infornation_schema.tables where table_name like ...
推荐阅读
- c# - 票据上热敏打印机顶部的空白区域
- javascript - 如何在 React 中正确实现嵌套的动态表单
- python - 键盘记录器卡在循环中
- ios - Swift MeasurementFormatter 错误地将距离转换为英里
- ms-access - 从 MS Access 中的表编译计数时遇到问题
- c - float、double 和 long double 之间没有区别吗?
- javascript - 如何从模拟模块模拟多个值?
- php - 我有一个可以提交的表单,但是当我添加文件上传功能时它不起作用
- java - Spring Data/JPA:如何保存具有多个子集合的项目?
- java - 我有一个休眠问题。启动我的应用程序时速度很慢,使用休眠启动第一个 sessionFactory 需要 2 分钟