0

我已经绊倒了一段时间了。我有一个名为的表,gears其中包含名称为:idmid和. 我想搜索这个表并以 csv 格式返回一些独特的 s列表。例如,如果我可以使用:cidinstalledmidcidcid = $cid

$query = $database -> query("SELECT COUNT(mid), GROUP_CONCAT(mid) FROM gears WHERE cid=$cid", __LINE__, __FILE__);
$gears_installed = $database -> get_result($query);
$gears = $database -> get_result($query, 0, 1);

不用担心函数名称,它们完全符合人们的预期。因此,如果该特定有 3 行$cid,使用mids: banklottery然后post$gears_installed等于 3 并且$gears将等于bank,lottery,post。这按预期工作。

现在谈谈我的问题。每个唯一的mid都有自己的表,名为settings_mid_here. 即,对于上述三个,我有表格settings_banksettings_lottery最后settings_post。这些表中的每一个也将有一个名为的列cid(这就是这两个表的关联方式)。如何运行一个查询以从每个表中返回整行 where cid=$cid?我不想为SELECT * FROM settings_bank WHERE cid=$cidandSELECT * FROM settings_post WHERE cid=$cid和 finally运行单独的查询SELECT * FROM settings_post WHERE cid=$cid,因为这可能会导致在一页加载时产生大约 10 个额外的查询(目前有 10 个不同mid的 s)。

如您所见,问题是动态的。它必须能够适应不同数量的mids,以某种方式区分每个表中的设置(例如,settings_bank可能有一个带有 name 的列name,因此可能是settings_post)。最后,如果不存在对应于给定的行,它还必须能够返回默认行(非空值)$cid

一项复杂的任务,但我希望有人可以帮助我,因为我无法到达任何地方。

4

2 回答 2

2
$queries = array();
foreach(explode(',', $gears) as $gear) {
    $queries[] = "SELECT '$gear' AS gearname, settings_$gear.* FROM settings_$gear WHERE cid=$cid";
}
$sql = implode(' UNION ', $queries);
$query2 = $database->query($sql);

此查询将为每个表返回一行,并带有一个额外的gearname列来指示该行来自哪个表。

或者您可以动态创建 JOIN:

$gears_array = explode(',', $gears);
$joins = implode(' JOIN ', $gears_array);
$wheres = implode(' AND ',
                  array_map(function($g) use ($cid) {
                    return "$g.cid = $cid";
                  }, $gears_array));
$sql = "SELECT * FROM $joins WHERE $wheres";
$query2 = $database->query($sql);
于 2013-10-12T18:58:00.367 回答
0

This is not really an answer to your specific question, simply because there's no way to accomplish what you are trying with one query.

The reason is simple: RDBMSs are not designed to work this way. Tables are supposed to store data that represent entities and relations. In your case, for each distinct value of mid, a table named settings_{mid} must exist, thus forcing the mid column implicitly store (a part of) a table name. But that's not data, that's metadata.

That would not really be a problem if SQL syntax could accept variable, parametrized, column-related or arbitary table names. But it doesn't. And that's by design. Instead, an RDBMS provides you with all the tools you could ever need to relate your data to each other. By using it the intended way, you'll never have to resort to such 'dynamic' tricks.

In your case, there should be one config table with a mid column to distinguish the rows that refer to the specific mid value. Then, the query would be simple:

select * from `config` where mid='$mid' and cid='$cid'

This is the relational way. Thus the R in RDBMS. There's absolutely no reason at all to mix data with metadata. If you do, you move the relation resolution problem in higher levels of the application model.

And one last thing: One might argue that the config_{mid} tables might have similar but not identical structure. There's a solution for that too: IS-A relations.

Having said that, for your specific problem, a solution along the lines of Barmar's answer would do the trick.

于 2013-10-12T20:16:33.083 回答