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