Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 动态MySQL查询:连接来自多个表的结果_Php_Mysql_Sql_Join - Fatal编程技术网

Php 动态MySQL查询:连接来自多个表的结果

Php 动态MySQL查询:连接来自多个表的结果,php,mysql,sql,join,Php,Mysql,Sql,Join,这是我一段时间以来遇到的问题。我有一个名为gears的表,其中包含名为id、mid、cid和的行。我想搜索此表并以csv格式返回一些唯一的cid的mids列表。例如,如果cid=$cid我可以使用: $query = $database -> query("SELECT COUNT(mid), GROUP_CONCAT(mid) FROM gears WHERE cid=$cid", __LINE__, __FILE__); $gears_installed = $database -&g

这是我一段时间以来遇到的问题。我有一个名为
gears
的表,其中包含名为
id
mid
cid
的行。我想搜索此表并以csv格式返回一些唯一的
cid
mid
s列表。例如,如果
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:
bank
lotking
post
,那么
$gears\u安装的
将等于3,
$gears
将等于
bank,lotking,post
。这正是我们想要的

现在谈谈我的问题。每个唯一的
mid
都有自己的表,在这里命名为
settings\u mid\u
。也就是说,对于以上三个,我有表
settings\u bank
settings\u lotking
,最后是
settings\u post
。这些表中的每一个都有一个名为
cid
的列(这就是二者之间的关系)。如何运行一个查询,从
cid=$cid
的每个表返回整行?我不想对
SELECT*FROM settings\u bank其中cid=$cid
SELECT*FROM settings\u post其中cid=$cid
以及最后
SELECT*FROM settings\u post其中cid=$cid
运行单独的查询,因为这可能会导致在一次页面加载中产生大约10个额外的查询(目前有10个不同的
mid
s)

正如你所看到的,问题是动态的。它必须能够适应不同数量的
mid
s,以某种方式区分每个表中的设置(例如
settings\u bank
可能有一个名为
name
的列,也可能是
settings\u post
)。最后,如果不存在与给定
$cid
对应的行,它还必须能够返回默认行(非空值)

这是一项复杂的任务,但我希望有人能帮助我,因为我还没有取得任何进展

$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
列,以指示该行来自哪个表

或者,您可以动态创建联接:

$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);

这并不是对您的特定问题的真正回答,只是因为您无法通过一个查询来完成您正在尝试的内容

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

如果SQL语法可以接受变量、参数化、列相关或任意的表名,那么这并不是一个真正的问题。但事实并非如此。这是故意的。相反,RDBMS为您提供了将数据相互关联所需的所有工具。通过按预期方式使用它,您将永远不必求助于此类“动态”技巧

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

select * from `config` where mid='$mid' and cid='$cid'
这是关系方式。因此,关系数据库管理系统中的R。完全没有理由将数据与元数据混用。如果您这样做,您就可以将关系解决问题转移到应用程序模型的更高级别

最后一件事是:
config{mid}
表可能具有相似但不完全相同的结构。也有一个解决方案:


话虽如此,对于您的具体问题,按照Barmar的答案找到一个解决方案就可以了。

我有一些想法,但我只能在收集一些方案和一些演示数据以测试查询时提供帮助。否则,这只是一个聪明的猜测。您的意思是,每次
gears
表中出现新的
mid
时,您都会创建一个新表?使用cid=3@geomagas
gears
表可以多次包含特定的
mid
。可以说,
gears
表将在一个
cid
帐户上为每个
mid
安装一行。例如,每个
mid
都是一个小部件。是的,但我不是这么要求的。假设我在
gears
中添加了一行,其中包含一个以前不存在的
mid='somewidget'
。我是否也必须创建一个
设置\u somewidget
表?我已经为一个测试用例运行了此操作:
选择'currency'作为gearname,*来自设置\u currency,其中cid=3
,但这会给出一个错误(由于
将'currency'作为gearname
部分)。修复了它。在执行此操作时,MySQL需要在
*
之前有一个明确的表名。这非常有效,直到两个表的列数不同(我就是这种情况)-在这一点上,它会崩溃并抛出一个错误。我曾想过做类似于
选择一个*,b.*从设置中\u currency a LEFT JOIN settings\u在b.cid=a.cid上发布b,其中a.cid=$cid
,但我不知道如何对多个表执行此操作,现在存在无法将列与其原始表区分开来的问题。例如,将有两列名为
name
,一列来自
settings\u currency
,另一列来自
settings\u post
。我添加了一个连接解决方案。虽然我想知道应用程序将如何处理所有这些动态数据——如果表具有不同的模式,应用程序将如何知道结果中的内容?我最初的想法是使用
config
表,但由于每个
mid
表都有任意数量的“设置”,因此这是不可能的