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

后端 未结 22 1738
爱一瞬间的悲伤
爱一瞬间的悲伤 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:40

    PHP 7.2 + MySQL/Mariadb

    MySQL will send you multiple fields with the same name. Even in the terminal client. But if you want an associative array, you'll have to make the keys yourself.

    Thanks to @axelbrz for the original. I've ported it to newer php and cleaned it up a little:

    function mysqli_rows_with_columns($link, $query) {
        $result = mysqli_query($link, $query);
        if (!$result) {
            return mysqli_error($link);
        }
        $field_count = mysqli_num_fields($result);
        $fields = array();
        for ($i = 0; $i < $field_count; $i++) {
            $field = mysqli_fetch_field_direct($result, $i);
            $fields[] = $field->table . '.' . $field->name; # changed by AS
            #$fields[] = $field->orgtable . '.' . $field->orgname; # actual table/field names
        }
        $rows = array();
        while ($row = mysqli_fetch_row($result)) {
            $new_row = array();
            for ($i = 0; $i < $field_count; $i++) {
                $new_row[$fields[$i]] = $row[$i];
            }
            $rows[] = $new_row;
        }
        mysqli_free_result($result);
        return $rows;
    }
    
    $link = mysqli_connect('localhost', 'fixme', 'fixme', 'fixme');
    print_r(mysqli_rows_with_columns($link, 'select foo.*, bar.* from foo, bar'));
    
    0 讨论(0)
  • 2020-12-02 06:41

    What I do is use Excel to concatenate the procedure. For instance, first I select * and get all of the columns, paste them in Excel. Then write out the code I need to surround the column. Say i needed to ad prev to a bunch of columns. I'd have my fields in the a column and "as prev_" in column B and my fields again in column c. In column d i'd have a column.

    Then use concatanate in column e and merge them together, making sure to include spaces. Then cut and paste this into your sql code. I've also used this method to make case statements for the same field and other longer codes i need to do for each field in a multihundred field table.

    0 讨论(0)
  • 2020-12-02 06:42

    This question is very useful in practice. It's only necessary to list every explicit columns in software programming, where you pay particular careful to deal with all conditions.

    Imagine when debugging, or, try to use DBMS as daily office tool, instead of something alterable implementation of specific programmer's abstract underlying infrastructure, we need to code a lot of SQLs. The scenario can be found everywhere, like database conversion, migration, administration, etc. Most of these SQLs will be executed only once and never be used again, give the every column names is just waste of time. And don't forget the invention of SQL isn't only for the programmers use.

    Usually I will create a utility view with column names prefixed, here is the function in pl/pgsql, it's not easy but you can convert it to other procedure languages.

    -- Create alias-view for specific table.
    
    create or replace function mkaview(schema varchar, tab varchar, prefix varchar)
        returns table(orig varchar, alias varchar) as $$
    declare
        qtab varchar;
        qview varchar;
        qcol varchar;
        qacol varchar;
        v record;
        sql varchar;
        len int;
    begin
        qtab := '"' || schema || '"."' || tab || '"';
        qview := '"' || schema || '"."av' || prefix || tab || '"';
        sql := 'create view ' || qview || ' as select';
    
        for v in select * from information_schema.columns
                where table_schema = schema and table_name = tab
        loop
            qcol := '"' || v.column_name || '"';
            qacol := '"' || prefix || v.column_name || '"';
    
            sql := sql || ' ' || qcol || ' as ' || qacol;
            sql := sql || ', ';
    
            return query select qcol::varchar, qacol::varchar;
        end loop;
    
        len := length(sql);
        sql := left(sql, len - 2); -- trim the trailing ', '.
        sql := sql || ' from ' || qtab;
    
        raise info 'Execute SQL: %', sql;
        execute sql;
    end
    $$ language plpgsql;
    

    Examples:

    -- This will create a view "avp_person" with "p_" prefix to all column names.
    select * from mkaview('public', 'person', 'p_');
    
    select * from avp_person;
    
    0 讨论(0)
  • 2020-12-02 06:43

    select * usually makes for bad code, as new columns tend to get added or order of columns change in tables quite frequently which usually breaks select * in a very subtle ways. So listing out columns is the right solution.

    As to how to do your query, not sure about mysql but in sqlserver you could select column names from syscolumns and dynamically build the select clause.

    0 讨论(0)
  • 2020-12-02 06:47

    Cant do this without aliasing , simply because, how are you going to reference a field in the where clause, if that field exists in the 2 or 3 tables you are joining? It will be unclear for mysql which one you are trying to reference.

    0 讨论(0)
  • 2020-12-02 06:49

    There is a direct answer to your question for those who use the MySQL C-API.

    Given the SQL:

      SELECT a.*, b.*, c.* FROM table_a a JOIN table_b b USING (x) JOIN table_c c USING (y)
    

    The results from 'mysql_stmt_result_metadata()' gives the definition of your fields from your prepared SQL query into the structure MYSQL_FIELD[]. Each field contains the following data:

      char *name;                 /* Name of column (may be the alias) */
      char *org_name;             /* Original column name, if an alias */
      char *table;                /* Table of column if column was a field */
      char *org_table;            /* Org table name, if table was an alias */
      char *db;                   /* Database for table */
      char *catalog;              /* Catalog for table */
      char *def;                  /* Default value (set by mysql_list_fields) */
      unsigned long length;       /* Width of column (create length) */
      unsigned long max_length;   /* Max width for selected set */
      unsigned int name_length;
      unsigned int org_name_length;
      unsigned int table_length;
      unsigned int org_table_length;
      unsigned int db_length;
      unsigned int catalog_length;
      unsigned int def_length;
      unsigned int flags;         /* Div flags */
      unsigned int decimals;      /* Number of decimals in field */
      unsigned int charsetnr;     /* Character set */
      enum enum_field_types type; /* Type of field. See mysql_com.h for types */
    

    Take notice the fields: catalog,table,org_name

    You now know which fields in your SQL belongs to which schema (aka catalog) and table. This is enough to generically identify each field from a multi-table sql query, without having to alias anything.

    An actual product SqlYOG is show to use this exact data in such a manor that they are able to independently update each table of a multi-table join, when the PK fields are present.

    0 讨论(0)
提交回复
热议问题