动态MySQL查询:加入来自众多表的结果

时间:2013-10-12 18:42:28

标签: php mysql sql join

我现在已经磕磕绊绊了一段时间。我有一个名为gears的表,其中包含名称为idmidcidinstalled的行。我想搜索此表并以csv格式返回mid的列表,以获取一些唯一的cid。例如,如果cid = $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);

不要担心功能名称,它们完全按照预期执行。因此,如果特定$cid有3行,mid s:banklotterypost,那么$gears_installed将等于3和$gears等于bank,lottery,post。这可以按预期工作。

现在回答我的问题。每个唯一mid都有自己的表,名为settings_mid_here。即,对于上述三个,我有表settings_banksettings_lottery和最后settings_post。这些表中的每一个都有一个名为cid的列(这两者可以相关联)。如何运行一个查询以从cid=$cid的每个表中返回整行?我不想为SELECT * FROM settings_bank WHERE cid=$cidSELECT * FROM settings_post WHERE cid=$cid以及最后SELECT * FROM settings_post WHERE cid=$cid运行单独的查询,因为这可能导致在一个页面加载上大约10个额外查询(目前, 10个不同的mid s。。

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

一项复杂的任务,但我希望有人可以帮我解决这个问题,因为我无法到达任何地方。

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

这不是对您的具体问题的真正答案,只是因为没有办法完成您使用一个查询尝试的内容

原因很简单:RDBMS不是以这种方式工作的。表应该存储表示实体关系数据。在您的情况下,对于mid的每个不同值,必须存在名为settings_{mid}的表,从而强制mid列隐式存储(部分)表名。但那不是数据,那是元数据

如果SQL语法可以接受变量,参数化,列相关或任意表名,那么这不会成为问题。但事实并非如此。那是设计。相反,RDBMS为您提供了将数据相互关联所需的所有工具。通过以预期的方式使用它,你将永远不必诉诸这种“动态”技巧。

在您的情况下,应该有一个带有config列的 mid表,以区分引用特定mid值的行。然后,查询将很简单:

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

这是关系方式。因此 RDBMS 中的 R 。绝对没有理由将数据与元数据混合在一起。如果这样做,则会在应用程序模型的更高级别中移动关系解析问题。

最后一件事:有人可能认为config_{mid}表可能有相似但不完全相同的结构。也有一个解决方案:IS-A relations

话虽如此,针对您的具体问题,按照Barmar的答案解决方案可以解决问题。