Php SQL从多个表中选择*
使用PHP/PDO/MySQL,当对多个表进行选择并且返回的数组键完全限定以避免列名冲突时,是否可以对列使用通配符 例如: 从表1、表2中选择*强> 给出: 数组键有“table1.id”、“table2.id”、“table1.name”等 我尝试了“SELECT table1.*,table2.*”,但返回的数组键未完全限定,因此同名列发生冲突并被覆盖。您可以执行以下操作:Php SQL从多个表中选择*,php,sql,mysql,database,pdo,Php,Sql,Mysql,Database,Pdo,使用PHP/PDO/MySQL,当对多个表进行选择并且返回的数组键完全限定以避免列名冲突时,是否可以对列使用通配符 例如: 从表1、表2中选择* 给出: 数组键有“table1.id”、“table2.id”、“table1.name”等 我尝试了“SELECT table1.*,table2.*”,但返回的数组键未完全限定,因此同名列发生冲突并被覆盖。您可以执行以下操作: SELECT Table1.*,Table2.xyz, Table2.abc,... From... 其中,使用“*”从
SELECT Table1.*,Table2.xyz, Table2.abc,... From...
其中,使用“*”从一个表中获取所有列,然后仅获取所需的另一个表中的列,因此不会发生冲突
您还可以使用列别名,在其中“重命名”列:
SELECT Table1.A AS T1_A,Table2.A AS T2_A,... From...
您的结果集将是T1_A和T2_A列不幸的是,PHP(特别是MySQL、PgSQL、MSSQL扩展)总是会在重叠的情况下覆盖您的列
我建议您在数据库中创建一个视图
,并为您的列设置别名,以便它们是“完全限定的”
例如:(MySQL)
语法可能并不完美,但您可以大致了解我所说的内容。不幸的是,没有;没有SQL语法来确保列名是唯一的 如果您确实不知道列的名称,并且必须使用
SELECT*
,那么您唯一的实际选择就是返回到一些外观非常难看的动态SQL,它可以检查表的结构并生成一个查询,该查询将使用表名前缀显式地选择所有列
我不知道您使用的是哪种RDBMS,但类似的东西应该可以在SQL Server上使用:
declare @columns table (idx int identity(1,1), tablename varchar(100), columnname varchar(100))
insert into @columns (tablename, columnname)
select tablename, columnname
from INFORMATION_SCHEMA.COLUMNS
where tablename in ('table_1', 'table_2')
declare @sql nvarchar(4000)
declare @i int
declare @cnt in
declare @col varchar(100)
declare @table varchar(100)
select @i = 0, @cnt = max(idx), @sql = '' from @columns
while @i < @cnt
begin
select @i = @i + 1
select @col = columnname, @table = tablename from @columns where idx = @i
if len(@sql) > 0
select @sql = @sql + ', '
select @sql = @sql + '[' + @table + '].[' + @col + '] as [' + @table + '_' + @col + ']'
end
select @sql = 'select ' + @sql + ' from table_1, table_2'
exec sp_executesql @sql
declare@columns表(idx int-identity(1,1)、tablename-varchar(100)、columnname-varchar(100))
插入@columns(表名、列名)
选择tablename,columnname
从信息_SCHEMA.COLUMNS
其中tablename位于('table_1'、'table_2')
声明@sql nvarchar(4000)
声明@i int
在中声明@cnt
声明@col varchar(100)
声明@table varchar(100)
从@columns中选择@i=0、@cnt=max(idx),@sql=''
而@i<@cnt
开始
选择@i=@i+1
从@columns中选择@col=columnname、@table=tablename,其中idx=@i
如果len(@sql)>0
选择@sql=@sql+,'
选择@sql=@sql+'['+@table+'].['+@col+']作为['+@table+'.+@col+']'
结束
选择@sql='从表1、表2中选择'+@sql+'
exec sp_executesql@sql
是的,你可以。最简单的方法是使用pdo,尽管至少还有一些其他的扩展能够使用它
设置对象上的属性,而不是对象上的属性
就这样。然后您会得到关联数组键,如$row['myTable.myColumn']
。如果您也获取一个对象(例如通过PDO::fetch_object
),那么它也会起作用,因此要小心,因为您需要访问类似$obj->{'myTable.myColumn'}
*只有某些驱动程序才支持PDO::ATTR\u FETCH\u TABLE\u NAMES
属性。如果上述方法不起作用,这可能会起作用
$pdoStatement->setFetchMode(PDO::FETCH_NUM);
$pdoStatement->execute();
//build our associative array keys
$qualifiedColumnNames = array();
for ($i = 0; $i < $pdoStatement->columnCount(); $i++) {
$columnMeta = $pdoStatement->getColumnMeta($i);
$qualifiedColumnNames[] = "$columnMeta[table].$columnMeta[name]";
}
//fetch results and combine with keys
while ($row = $pdoStatement->fetch()) {
$qualifiedRow = array_combine($qualifiedColumnNames, $row);
print_r($qualifiedRow);
}
这也适用于表别名(在php 7.1中测试)-限定的列名将使用表别名。不知羞耻地从@goat:
// Workaround for setAttribute(PDO::ATTR_FETCH_TABLE_NAMES, true);
function pdoStatementExecuteAndFetchObjWithTableNames(PDOStatement $statement)
{
$statement->setFetchMode(PDO::FETCH_NUM);
$statement->execute();
//build our associative array keys
$qualifiedColumnNames = array();
for ($i = 0; $i < $statement->columnCount(); $i++) {
$columnMeta = $statement->getColumnMeta($i);
$qualifiedColumnNames[] = "$columnMeta[table].$columnMeta[name]";
}
//fetch results and combine with keys
while ($row = $statement->fetch()) {
$qualifiedRow = array_combine($qualifiedColumnNames, $row);
yield (object) $qualifiedRow;
}
}
//setAttribute的解决方法(PDO::ATTR_FETCH_TABLE_NAMES,true);
函数pdoStatementExecuteAndFetchObjWithTableNames(PDOStatement$语句)
{
$statement->setFetchMode(PDO::FETCH_NUM);
$statement->execute();
//构建我们的关联数组键
$qualifiedColumnNames=array();
对于($i=0;$i<$statement->columnCount();$i++){
$columnMeta=$statement->getColumnMeta($i);
$qualifiedColumnNames[]=“$columnMeta[表]。$columnMeta[名称]”;
}
//获取结果并与键组合
而($row=$statement->fetch()){
$qualifiedRow=array\u combine($qualifiedColumnNames,$row);
收益(对象)$qualifiedRow;
}
}
注意:如果您使用:
从我的\u表中选择1作为我的\u表\u别名
然后,您将获得我的表格。我希望
我的表\u别名
。我使用PHP5.6和sqlite驱动程序得到了这个结果。注意不同表中同名的colun-您只会得到一个实例。是的。我注意到,如果我知道每个表中的列数,我可以通过数字索引检索值,但事实并非如此。您需要这样做的具体原因是什么?不管怎样,从多个表中使用SELECT*通常是个坏主意,所以我只是想在给你答案之前弄清楚你这样做背后的思维过程。同意。除非您不知道列名(我打赌您知道),否则选择*永远不是一个好主意:您运行的是两个查询,而不是一个查询(一个查询列名,然后是您的查询),并且很可能返回的数据比您需要的多。现在可能没有注意到问题,但如果其中一些字段是BLOB或有大量文本,您会注意到。@Stephen我有几个具有不相关列的“内容”表和一个包含其他表类似数据的“元数据”表。我用元数据表(比如说一对一关系)查询一个内容表中的所有内容表列。我希望能更好地解释,但我的数据库行话是有限的@汤姆:我当然知道这些专栏的名字。只是不想把它们打印出来!首先,您要指定列名-我们不知道这些列,如果xyz或abc也在表1中呢?。第二,正如我所说的,我尝试了通配符。如果我们不知道表中的列,那么重命名它们就有点困难。你怎么可能不知道这些列呢?这是用动态SQL生成的吗?如果是这样,则动态构建选择列表。涉及的表是动态的。我试图避免编写处理每种“类型”表的代码。@zaf如果您不知道列名,如何知道您需要哪些列名/哪些列名正在被覆盖?在我写这篇文章时,我本可以手工编写sql查询。坚持
$pdoStatement->setFetchMode(PDO::FETCH_NUM);
$pdoStatement->execute();
//build our associative array keys
$qualifiedColumnNames = array();
for ($i = 0; $i < $pdoStatement->columnCount(); $i++) {
$columnMeta = $pdoStatement->getColumnMeta($i);
$qualifiedColumnNames[] = "$columnMeta[table].$columnMeta[name]";
}
//fetch results and combine with keys
while ($row = $pdoStatement->fetch()) {
$qualifiedRow = array_combine($qualifiedColumnNames, $row);
print_r($qualifiedRow);
}
$res = mysql_query($sql);
//build our associative array keys
$qualifiedColumnNames = array();
for ($i = 0; $i < mysql_num_fields($res); $i++) {
$columnMeta = mysql_fetch_field($res, $i);
$qualifiedColumnNames[] = "$columnMeta[table].$columnMeta[name]";
}
//fetch results and combine with keys
while ($row = mysql_fetch_row($res)) {
$qualifiedRow = array_combine($qualifiedColumnNames, $row);
print_r($qualifiedRow);
}
$res = $mysqli->query($sql);
//build our associative array keys
$qualifiedColumnNames = array();
foreach ($res->fetch_fields() as $columnMeta) {
$qualifiedColumnNames[] = "{$columnMeta->table}.{$columnMeta->name}";
}
//fetch results and combine with keys
while ($row = $res->fetch_row()) {
$qualifiedRow = array_combine($qualifiedColumnNames, $row);
print_r($qualifiedRow);
}
// Workaround for setAttribute(PDO::ATTR_FETCH_TABLE_NAMES, true);
function pdoStatementExecuteAndFetchObjWithTableNames(PDOStatement $statement)
{
$statement->setFetchMode(PDO::FETCH_NUM);
$statement->execute();
//build our associative array keys
$qualifiedColumnNames = array();
for ($i = 0; $i < $statement->columnCount(); $i++) {
$columnMeta = $statement->getColumnMeta($i);
$qualifiedColumnNames[] = "$columnMeta[table].$columnMeta[name]";
}
//fetch results and combine with keys
while ($row = $statement->fetch()) {
$qualifiedRow = array_combine($qualifiedColumnNames, $row);
yield (object) $qualifiedRow;
}
}