SQL select join: is it possible to prefix all columns as 'prefix.*'?

后端 未结 22 1794
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-02 06:20

I\'m wondering if this is possible in SQL. Say you have two tables A and B, and you do a select on table A and join on table B:

SELECT a.*, b.* FROM TABLE_A a         


        
22条回答
  •  天命终不由人
    2020-12-02 06:35

    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 "
    $query
    "; $posts = $wpdb->get_results($query, OBJECT); echo "
    ";
        print_r($posts);
        echo "
    "; }

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

提交回复
热议问题