我有一个名为“bookfeather”的MySQL数据库。它包含56个表。每个表都具有以下结构:
id site votes_up votes_down
“网站”的值是书名。 “votes_up”的值是一个整数。有时,“网站”的唯一值会出现在多个表格中。
对于整个数据库中的每个唯一值“site”,我想总结所有56个表中的“votes_up”。然后我想打印排名为“votes_up”的“网站”的前25个值。
我如何在PHP中执行此操作?
提前致谢,
约翰
答案 0 :(得分:1)
你可以做这样的事情(警告:前面的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
但是,正如戴维所问,你的数据有是这样的吗?有更有效的方法来存储这种数据。
编辑:您刚刚在评论中提到过,您希望将来有超过56个表 - 在使用这种SQL之前,我会研究一下您可以使用UNION的表数的MySQL限制。
答案 1 :(得分:0)
可以使用如下语句生成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上)。
答案 2 :(得分:0)
基本思想是在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";
}
答案 3 :(得分:0)
这是一个应该完成它的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)
答案 4 :(得分:0)
“我允许用户将表添加到数据库中。” - 我希望你的所有用户都是仁慈,值得信赖和有能力的。您是否担心人们丢弃或截断表,创建错误的新表来破坏您的代码或其他类似的东西?当用户可以直接登录到您的数据库并更改架构时,您有什么样的安全性?
这是关系数据库规范化的tutorial。也许它会有所帮助。
以防万一其他人想要找到这样的东西,这里有一张表可以做你想做的事情:
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')
我强烈要求你重新考虑。