Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/246.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.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 SQL从多个表中选择*_Php_Sql_Mysql_Database_Pdo - Fatal编程技术网

Php SQL从多个表中选择*

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... 其中,使用“*”从

使用PHP/PDO/MySQL,当对多个表进行选择并且返回的数组键完全限定以避免列名冲突时,是否可以对列使用通配符

例如:

从表1、表2中选择*

给出:

数组键有“table1.id”、“table2.id”、“table1.name”等

我尝试了“SELECT table1.*,table2.*”,但返回的数组键未完全限定,因此同名列发生冲突并被覆盖。

您可以执行以下操作:

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;
  }  
}