Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Select * from multiple tables

Using PHP/PDO/MySQL is it possible to use a wildcard for the columns when a select is done on multiple tables and the returned array keys are fully qualified to avoid column name clash?

example:

SELECT * from table1, table2;

gives:

Array keys are 'table1.id', 'table2.id', 'table1.name' etc.

I tried "SELECT table1.*,table2.* ..." but the returned array keys were not fully qualified so columns with the same name clashed and were overwritten.

like image 955
zaf Avatar asked Mar 26 '10 13:03

zaf


People also ask

Can you select all from multiple tables in SQL?

In SQL we can retrieve data from multiple tables also by using SELECT with multiple tables which actually results in CROSS JOIN of all the tables.

Can we use select * with group by?

Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause. The original idea was to create the table in beginning of the query, so the (SELECT * FROM #TBL) could be used on the query itself, instead of defining the names on each GROUP BY.

Why select * is not recommended?

By using SELECT * , you can return unnecessary data that will just be ignored. But fetching that data is not free of cost. This results in some wasteful IO cycles on the DB end since you will be reading all of that data off the pages. Perhaps you could have read the data from index pages.


1 Answers

Yes, you can. The easiest way is with pdo, although there's at least a few other extensions which are capable of it.

pdo

Set the attribute on the PDO object, not the PDOStatment.

$PDO->setAttribute(PDO::ATTR_FETCH_TABLE_NAMES, true);

That's it. Then you get associative array keys like $row['myTable.myColumn']. It works if you fetch an object too (eg via PDO::FETCH_OBJECT) so beware, because you need to access the properties like $obj->{'myTable.myColumn'}

*The manual says the PDO::ATTR_FETCH_TABLE_NAMES attribute is only supported by certain drivers. If the above doesn't work, this might work instead.

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

Same basic pattern is used for other database extensions

mysql

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

mysqli

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

This should also work with table aliases (tested in php 7.1) - the qualified column name will use the table alias.

like image 62
goat Avatar answered Sep 23 '22 14:09

goat