[英]Summing a field from all tables in a database
我有一个名为“ bookfeather”的MySQL数据库。 它包含56个表。 每个表具有以下结构:
id site votes_up votes_down
“ site”的值是书名。 “ votes_up”的值是一个整数。 有时,一个“站点”的唯一值出现在多个表中。
对于整个数据库中的每个唯一值“ site”,我想对所有56个表中的“ votes_up”求和。 然后,我想打印按总“ votes_up”排名的“网站”的前25个值。
如何在PHP中做到这一点?
提前致谢,
约翰
您可以执行以下操作(警告:SQL非常差)
select site, sum(votes_up) votes_up
from (
select site, votes_up from table_1
UNION
select site, votes_up from table_2
UNION
...
UNION
select site, votes_up from table_56
) group by site order by sum(votes_up) desc limit 25
但是,正如Dav所问,您的数据是否必须像这样? 有很多更有效的方法来存储此类数据。
编辑:您刚刚在一条评论中提到,您希望将来会有56个以上的表-在继续使用这种SQL之前,我将研究MySQL对可以UNION的表数量的限制。
Ian Clelland答案的UNION部分可以使用如下语句生成。 表INFORMATION_SCHEMA.COLUMNS具有用于获取所有表的TABLE_NAME列。
select * from information_schema.columns
where table_schema not like 'informat%'
and column_name like 'VOTES_UP'
用UNION ALL代替UNION将所有内部SELECT连接起来。 UNION正在执行隐式DISTINCT(在oracle上)。
基本思想是在PHP中遍历所有表(使用SQL SHOW TABLES
语句或类似语句),然后对每个表遍历行( SELECT site,votes_up FROM $table
)。 然后,针对每一行,对照您要构建的数组检查站点,并以站点作为键并投票支持值。 如果站点已经在数组中,则适当增加其投票; 否则,添加它。
类似于PHP的伪代码:
// Build an empty array for use later
$votes_array = empty_array();
// Get all the tables and iterate over them
$tables = query("SHOW TABLES");
for($table in $tables) {
$rows = query("SELECT site,votes_up FROM $table");
// Iterate over the rows in each table
for($row in $rows) {
$site = $row['site'];
$votes = $row['votes_up'];
// If the site is already in the array, increment votes; otherwise, add it
if(exists_in_array($site, $votes_array)) {
$votes_array[$site] += $votes;
} else {
insert_into_array($site => $votes);
}
}
}
// Get the sites and votes as lists, and print out the top 25
$sorted_sites = array_keys($votes_array);
$sorted_votes = array_values($votes_array);
for($i = 0; $i < 25; $i++) {
print "Site " . $sorted_sites[$i] . " has " . $sorted_votes[$i] . " votes";
}
这是应该完成的PHP代码片段。 我尚未对其进行测试,因此可能会有一些错别字和其他内容,请确保您替换了DB_NAME
$result = mysql_query("SHOW TABLES"); $tables = array(); while ($row = mysql_fetch_assoc($result)) { $tables[] = '`'.$row["Tables_in_DB_NAME"].'`'; } $subQuery = "SELECT site, votes_up FROM ".implode(" UNION ALL SELECT site, votes_up FROM ",$tables); // Create one query that gets the data you need $sqlStr = "SELECT site, sum(votes_up) sumVotesUp FROM ( ".$subQuery." ) subQuery GROUP BY site ORDER BY sum(votes_up) DESC LIMIT 25"; $result = mysql_query($sqlStr); $arr = array(); while ($row = mysql_fetch_assoc($result)) { $arr[] = $row["site"]." - ".$row["sumVotesUp"]; } print_r($arr)
“我允许用户将表添加到数据库中。” -希望您所有的用户都是友好,可信赖和有能力的。 您是否担心人们会删除或截断表,创建不正确的新表而破坏您的代码或诸如此类的事情? 当用户可以直接登录数据库并更改架构时,您具有哪种安全性?
这是有关关系数据库规范化的教程 。 也许会有所帮助。
以防万一您想要找到其他人之后的样子,这里有一张表可以满足您的需求:
create database bookfeather;
create user bookfeather identified by 'bookfeather';
grant all on bookfeather.* to 'bookfeather'@'%';
use bookfeather;
create table if not exists book
(
id int not null auto_increment,
title varchar(255) not null default '',
upvotes integer not null default 0,
downvotes integer not null default 0,
primary key(id),
unique(title)
);
您可以通过UPDATE上下表决标题:
update book set upvotes = upvotes + 1 where id = ?
添加新书就像添加另一行一样容易:
insert into book(title) values('grails in action')
我强烈建议您重新考虑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.