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

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

    I implemented a solution based upon the answer suggesting using dummy or sentinel columns in node. You would use it by generating SQL like:

    select 
        s.*
      , '' as _prefix__creator_
      , u.*
      , '' as _prefix__speaker_
      , p.*
    from statements s 
      left join users u on s.creator_user_id = u.user_id
      left join persons p on s.speaker_person_id = p.person_id
    

    And then post-processing the row you get back from your database driver like addPrefixes(row).

    Implementation (based upon the fields/rows returned by my driver, but should be easy to change for other DB drivers):

    const PREFIX_INDICATOR = '_prefix__'
    const STOP_PREFIX_INDICATOR = '_stop_prefix'
    
    /** Adds a <prefix> to all properties that follow a property with the name: PREFIX_INDICATOR<prefix> */
    function addPrefixes(fields, row) {
      let prefix = null
      for (const field of fields) {
        const key = field.name
        if (key.startsWith(PREFIX_INDICATOR)) {
          if (row[key] !== '') {
            throw new Error(`PREFIX_INDICATOR ${PREFIX_INDICATOR} must not appear with a value, but had value: ${row[key]}`)
          }
          prefix = key.substr(PREFIX_INDICATOR.length)
          delete row[key]
        } else if (key === STOP_PREFIX_INDICATOR) {
          if (row[key] !== '') {
            throw new Error(`STOP_PREFIX_INDICATOR ${STOP_PREFIX_INDICATOR} must not appear with a value, but had value: ${row[key]}`)
          }
          prefix = null
          delete row[key]
        } else if (prefix) {
          const prefixedKey = prefix + key
          row[prefixedKey] = row[key]
          delete row[key]
        }
      }
      return row
    }
    

    Test:

    const {
      addPrefixes,
      PREFIX_INDICATOR,
      STOP_PREFIX_INDICATOR,
    } = require('./BaseDao')
    
    describe('addPrefixes', () => {
      test('adds prefixes', () => {
        const fields = [
          {name: 'id'},
          {name: PREFIX_INDICATOR + 'my_prefix_'},
          {name: 'foo'},
          {name: STOP_PREFIX_INDICATOR},
          {name: 'baz'},
        ]
        const row = {
          id: 1,
          [PREFIX_INDICATOR + 'my_prefix_']: '',
          foo: 'bar',
          [STOP_PREFIX_INDICATOR]: '',
          baz: 'spaz'
        }
        const expected = {
          id: 1,
          my_prefix_foo: 'bar',
          baz: 'spaz',
        }
        expect(addPrefixes(fields, row)).toEqual(expected)
      })
    })
    
    0 讨论(0)
  • 2020-12-02 06:58

    Recently ran into this issue in NodeJS and Postgres.

    ES6 approach

    There aren't any RDBMS features I know of that provide this functionality, so I created an object containing all my fields, e.g.:

    const schema = { columns: ['id','another_column','yet_another_column'] }
    

    Defined a reducer to concatenate the strings together with a table name:

    const prefix = (table, columns) => columns.reduce((previous, column) => {
      previous.push(table + '.' + column + ' AS ' + table + '_' + column);
      return previous;
    }, []);
    

    This returns an array of strings. Call it for each table and combine the results:

    const columns_joined = [...prefix('tab1',schema.columns), ...prefix('tab2',schema.columns)];
    

    Output the final SQL statement:

    console.log('SELECT ' + columns_joined.join(',') + ' FROM tab1, tab2 WHERE tab1.id = tab2.id');
    
    0 讨论(0)
  • 2020-12-02 06:59

    I am in kind of the same boat as OP - I have dozens of fields from 3 different tables that I'm joining, some of which have the same name(ie. id, name, etc). I don't want to list each field, so my solution was to alias those fields that shared a name and use select * for those that have a unique name.

    For example :

    table a : id, name, field1, field2 ...

    table b : id, name, field3, field4 ...

    select a.id as aID, a.name as aName, a. * , b.id as bID, b.name as bName, b. * .....

    When accessing the results I us the aliased names for these fields and ignore the "original" names.

    Maybe not the best solution but it works for me....i'm use mysql

    0 讨论(0)
  • 2020-12-02 07:01

    Or you could use Red Gate SQL Refactor or SQL Prompt, which expands your SELECT * into column lists with a click of the Tab button

    so in your case, if you type in SELECT * FROM A JOIN B ... Go to the end of *, Tab button, voila! you'll see SELECT A.column1, A.column2, .... , B.column1, B.column2 FROM A JOIN B

    It's not free though

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