SQL select join: is it possible to prefix all columns as 'prefix.*'?
It seems the answer to your question is no, however one hack you can use is to assign a dummy column to separate each new table. This works especially well if you're looping through a result set for a list of columns in a scripting language such as Python or PHP.
SELECT '' as table1_dummy, table1.*, '' as table2_dummy, table2.*, '' as table3_dummy, table3.* FROM table1
JOIN table2 ON table2.table1id = table1.id
JOIN table3 ON table3.table1id = table1.id
I realize this doesn't answer your question exactly, but if you're a coder this is a great way to separate tables with duplicate column names. Hope this helps somebody.
I see two possible situations here. First, you want to know if there is a SQL standard for this, that you can use in general regardless of the database. No, there is not. Second, you want to know with regard to a specific dbms product. Then you need to identify it. But I imagine the most likely answer is that you'll get back something like "a.id, b.id" since that's how you'd need to identify the columns in your SQL expression. And the easiest way to find out what the default is, is just to submit such a query and see what you get back. If you want to specify what prefix comes before the dot, you can use "SELECT * FROM a AS my_alias", for instance.
I totally understand why this is necessary - at least for me it's handy during rapid prototyping when there are a lot of tables necessary to be joined, including many inner joins. As soon as a column name is the same in a second "joinedtable.*" field wild card, the main table's field values are overriden with the joinedtable values. Error prone, frustrating and a violation of DRY when having to manually specify the table fields with aliases over and over...
Here is a PHP (Wordpress) function to achieve this through code generation together with an example of how to use it. In the example, it is used to rapidly generate a custom query that will provide the fields of a related wordpress post that was referenced through a advanced custom fields field.
function prefixed_table_fields_wildcard($table, $alias)
{
global $wpdb;
$columns = $wpdb->get_results("SHOW COLUMNS FROM $table", ARRAY_A);
$field_names = array();
foreach ($columns as $column)
{
$field_names[] = $column["Field"];
}
$prefixed = array();
foreach ($field_names as $field_name)
{
$prefixed[] = "`{$alias}`.`{$field_name}` AS `{$alias}.{$field_name}`";
}
return implode(", ", $prefixed);
}
function test_prefixed_table_fields_wildcard()
{
global $wpdb;
$query = "
SELECT
" . prefixed_table_fields_wildcard($wpdb->posts, 'campaigns') . ",
" . prefixed_table_fields_wildcard($wpdb->posts, 'venues') . "
FROM $wpdb->posts AS campaigns
LEFT JOIN $wpdb->postmeta meta1 ON (meta1.meta_key = 'venue' AND campaigns.ID = meta1.post_id)
LEFT JOIN $wpdb->posts venues ON (venues.post_status = 'publish' AND venues.post_type = 'venue' AND venues.ID = meta1.meta_value)
WHERE 1
AND campaigns.post_status = 'publish'
AND campaigns.post_type = 'campaign'
LIMIT 1
";
echo "<pre>$query</pre>";
$posts = $wpdb->get_results($query, OBJECT);
echo "<pre>";
print_r($posts);
echo "</pre>";
}
The output:
SELECT
`campaigns`.`ID` AS `campaigns.ID`, `campaigns`.`post_author` AS `campaigns.post_author`, `campaigns`.`post_date` AS `campaigns.post_date`, `campaigns`.`post_date_gmt` AS `campaigns.post_date_gmt`, `campaigns`.`post_content` AS `campaigns.post_content`, `campaigns`.`post_title` AS `campaigns.post_title`, `campaigns`.`post_excerpt` AS `campaigns.post_excerpt`, `campaigns`.`post_status` AS `campaigns.post_status`, `campaigns`.`comment_status` AS `campaigns.comment_status`, `campaigns`.`ping_status` AS `campaigns.ping_status`, `campaigns`.`post_password` AS `campaigns.post_password`, `campaigns`.`post_name` AS `campaigns.post_name`, `campaigns`.`to_ping` AS `campaigns.to_ping`, `campaigns`.`pinged` AS `campaigns.pinged`, `campaigns`.`post_modified` AS `campaigns.post_modified`, `campaigns`.`post_modified_gmt` AS `campaigns.post_modified_gmt`, `campaigns`.`post_content_filtered` AS `campaigns.post_content_filtered`, `campaigns`.`post_parent` AS `campaigns.post_parent`, `campaigns`.`guid` AS `campaigns.guid`, `campaigns`.`menu_order` AS `campaigns.menu_order`, `campaigns`.`post_type` AS `campaigns.post_type`, `campaigns`.`post_mime_type` AS `campaigns.post_mime_type`, `campaigns`.`comment_count` AS `campaigns.comment_count`,
`venues`.`ID` AS `venues.ID`, `venues`.`post_author` AS `venues.post_author`, `venues`.`post_date` AS `venues.post_date`, `venues`.`post_date_gmt` AS `venues.post_date_gmt`, `venues`.`post_content` AS `venues.post_content`, `venues`.`post_title` AS `venues.post_title`, `venues`.`post_excerpt` AS `venues.post_excerpt`, `venues`.`post_status` AS `venues.post_status`, `venues`.`comment_status` AS `venues.comment_status`, `venues`.`ping_status` AS `venues.ping_status`, `venues`.`post_password` AS `venues.post_password`, `venues`.`post_name` AS `venues.post_name`, `venues`.`to_ping` AS `venues.to_ping`, `venues`.`pinged` AS `venues.pinged`, `venues`.`post_modified` AS `venues.post_modified`, `venues`.`post_modified_gmt` AS `venues.post_modified_gmt`, `venues`.`post_content_filtered` AS `venues.post_content_filtered`, `venues`.`post_parent` AS `venues.post_parent`, `venues`.`guid` AS `venues.guid`, `venues`.`menu_order` AS `venues.menu_order`, `venues`.`post_type` AS `venues.post_type`, `venues`.`post_mime_type` AS `venues.post_mime_type`, `venues`.`comment_count` AS `venues.comment_count`
FROM wp_posts AS campaigns
LEFT JOIN wp_postmeta meta1 ON (meta1.meta_key = 'venue' AND campaigns.ID = meta1.post_id)
LEFT JOIN wp_posts venues ON (venues.post_status = 'publish' AND venues.post_type = 'venue' AND venues.ID = meta1.meta_value)
WHERE 1
AND campaigns.post_status = 'publish'
AND campaigns.post_type = 'campaign'
LIMIT 1
Array
(
[0] => stdClass Object
(
[campaigns.ID] => 33
[campaigns.post_author] => 2
[campaigns.post_date] => 2012-01-16 19:19:10
[campaigns.post_date_gmt] => 2012-01-16 19:19:10
[campaigns.post_content] => Lorem ipsum
[campaigns.post_title] => Lorem ipsum
[campaigns.post_excerpt] =>
[campaigns.post_status] => publish
[campaigns.comment_status] => closed
[campaigns.ping_status] => closed
[campaigns.post_password] =>
[campaigns.post_name] => lorem-ipsum
[campaigns.to_ping] =>
[campaigns.pinged] =>
[campaigns.post_modified] => 2012-01-16 21:01:55
[campaigns.post_modified_gmt] => 2012-01-16 21:01:55
[campaigns.post_content_filtered] =>
[campaigns.post_parent] => 0
[campaigns.guid] => http://example.com/?p=33
[campaigns.menu_order] => 0
[campaigns.post_type] => campaign
[campaigns.post_mime_type] =>
[campaigns.comment_count] => 0
[venues.ID] => 84
[venues.post_author] => 2
[venues.post_date] => 2012-01-16 20:12:05
[venues.post_date_gmt] => 2012-01-16 20:12:05
[venues.post_content] => Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
[venues.post_title] => Lorem ipsum venue
[venues.post_excerpt] =>
[venues.post_status] => publish
[venues.comment_status] => closed
[venues.ping_status] => closed
[venues.post_password] =>
[venues.post_name] => lorem-ipsum-venue
[venues.to_ping] =>
[venues.pinged] =>
[venues.post_modified] => 2012-01-16 20:53:37
[venues.post_modified_gmt] => 2012-01-16 20:53:37
[venues.post_content_filtered] =>
[venues.post_parent] => 0
[venues.guid] => http://example.com/?p=84
[venues.menu_order] => 0
[venues.post_type] => venue
[venues.post_mime_type] =>
[venues.comment_count] => 0
)
)