How to distinguish the same field names of two Oracle tables? - sql

I have two different table.
One table has 70 Columes, the other has 80.
I want to display all the Columes of the two tables.
But there are some Columes with the same Columes-name.
EX:
SELECT *
FROM TABLE1 A INNER JOIN
TABLE2 B ON A.ID = B.ID
enter image description here
I want to distinguish which table does the Columes comes from.
I know have to list your column list explicitly and provide aliases to them in the SELECT list.
How can I modify my program?
Is there any other easier way.
Because there are too many field names

You'll have to list your column list explicitly and provide aliases to them in the SELECT list.
SELECT
A.ID AS A_ID,
B.ID AS B_ID
FROM TABLE1 A INNER JOIN
TABLE2 B ON A.ID = B.ID
As a best practice
Never use SELECT * in production queries, always list the required columns explicitly. Why is SELECT * considered harmful?
When you have more than one table referenced in the query (e.g you join two tables), always give an alias to all tables and use that alias when you are referencing any columns of the tables.

You can build a query and let it to compose the query for you. It's not that hard as it seems
I've created tables TEST1 and TEST2 with identical column names and managed database to list me all the columns with prefixes.
select 'select ' txt from dual
union all
select listagg('t1.' || atc.COLUMN_NAME, ', ') within group (order by atc.COLUMN_NAME) || ', '
from all_tab_cols atc
where table_name = 'TEST1'
union all
select listagg('t2.' || atc.COLUMN_NAME, ', ') within group (order by atc.COLUMN_NAME)
from all_tab_cols atc
where table_name = 'TEST2';
The output is
TXT
----------
select
t1.NUM_COL, t1.TEXT_COL,
t2.NUM_COL, t2.TEXT_COL
So you may run the query, copy the output and then add the FROM and WHERE and other parts you need

If the only column names in common are used a JOIN keys, then you can phrase this as:
SELECT *
FROM TABLE1 A INNER JOIN
TABLE2 B
USING (ID);
The ID column only appears once in the result set.
If other columns are common, then you need to use column aliases. Sometimes, it is convenient to use something like this:
SELECT A.*, B.col1 as b_col1, B.col2 as b_col2, . . .
FROM TABLE1 A INNER JOIN
TABLE2 B
USING (ID);
To make this simpler, you can use the metadata tables.

Related

How to automatically rename column names in SELECT a.*, b.* to have ie. prefixes a_ and b_ in result column names?

I have two tables (a,b), or joining table to itself, having the same column names. (The table(s) is wide, having about hundred columns.)
Using:
SELECT a.*, b.*
FROM a LEFT JOIN b ON b.id=a.id AND b.date1=a.date2;
... works, but now if I want to make a view from it:
CREATE OR REPLACE VIEW v_test_ab AS
SELECT a.*, b.*
FROM a LEFT JOIN b ON b.id=a.id AND b.date1=a.date2;
... it cannot make a view, because there would be multiple columns with same name.
In PostgreSQL, is there any way to automatically rename the column names of a result table using given pattern?
Example something like:
CREATE OR REPLACE VIEW v_test_ab AS
SELECT a.* AS a_*, b.* AS b_*
FROM a LEFT JOIN b ON b.id=a.id AND b.date1=a.date2;
Or perhaps something like:
SELECT a.* AS generate_column_names('a_%', a.*)
, b.* AS generate_column_names('b_%', b.*)
Avoiding to need to write:
CREATE OR REPLACE VIEW v_test_ab AS
SELECT
a.id as a_id, a.date1 as a_date1, a.date2 as a_date2 -- and so on
, b.id as b_id, b.date1 as b_date1, b.date2 as b_date2 -- and so on
FROM a LEFT JOIN b ON b.id=a.id AND b.date1=a.date2;
I can of course use pattern matching search & replace in IDE-editor, but an end result looks like bloated. (The real world case I have, has four wide source tables with many same column names.)
While it is possible to wrap the creation query in an execute statement, joining the catalog to fetch the table and column names, it will be difficult to read.
Instead, the most simple and fast way would be to automatically build the list of column and to copy - paste it in your query.
As a bonus, the day someone asks to rename/alter/drop a specific column, there is a written record of its usage.
SELECT table_name || '.' || column_name || ' as a_' || column_name || ', '
FROM information_schema.columns
WHERE table_schema = 'my_schema'
AND table_name= 'my_tablename';
?column?
-------------------------
my_tablename.id as a_id,
my_tablename.title as a_title,
my_tablename.a as a_a,

How to print all columns when columns are dynamic and one common column is present?

Lets say i have 2 table A,B .In both the tables (id) is the common column ,and rest columns dynamic.so write a query to print id of "A" and rest all columns .
A(id,name,city),B(id,phone,phone_num). Here I only know "id" column ,rest columns(name,city,phone) are coming dynamically,So i can not use A.name,A.city,B.phone etc .In
select * from A FULL OUTER JOIN B ON A.id = B.id;
is printing id column twice.
If you want to display the id column only once, use the using clause for the join :
SELECT *
FROM tableA a
JOIN tableB b using (id)
The using clause as the effect that the join column(s) are only included once with select *.
If I'm not wrong, you want to display all the column of both the tables and the common column i.e id should come only once.If that's the case use the below query and replace the column name with the column names you want to display.
SELECT a.id,a.column1,a.column2,b.column1,b.column2
FROM tableA a
INNER JOIN tableB b ON a.id=b.id
Demo
create table my_table_1 (id int,c1 int,c2 int,c3 int);
create table my_table_2 (id int,c4 int,c5 int);
select array_to_string(array_agg (table_name || '.' || column_name::text),',')
from information_schema.columns
where table_name in ('my_table_1','my_table_2')
and not (table_name,column_name) = ('my_table_2','id')
my_table_1.id,my_table_1.c1,my_table_1.c2,my_table_1.c3,my_table_2.c4,my_table_2.c5

Getting common fields of two tables in PL/SQL

Suppose Table A and Table B have various fields. What is an easy way to get the common fields among Table A and Table B ? I want to do an inner join on these tables but I don't know what the common fields are.
Note that this is in PL/SQL. When I table A. or B. I get the list of fields names of each table in a drop down menu. But I would like to get the common fields.
It depends on what do you mean by "common fields".
If you want to get all colums which names are the same in both tables, then you can use this query:
SELECT t1.column_name
FROM user_tab_columns t1
JOIN user_tab_columns t2
ON t1.COLUMN_NAME = t2.COLUMN_NAME
/*
AND t1.DATA_TYPE = t2.DATA_TYPE
AND t1.DATA_LENGTH = t2.DATA_LENGTH
*/
WHERE t1.table_name = 'A'
AND t2.table_name = 'B'
;
Demo: http://sqlfiddle.com/#!4/2b662/1
But if you look at tables in the above demo, you will see that table A has a column named X with datatype VARCHAR2, and table B has also a column named X but of different type INT.
If you want to get all columns that have the same names, the same datatypes and the same length, then uncomment respective conditions in the above query.
Do mean something like this:
TableA has 2 columns: Id and Name.
TableB has 2 columns: Name and PhoneNumber
Query:
SELECT A.Id, A.Name, B.PhoneNumber
FROM TableA A, TableB B
WHERE A.Name = B.Name;
Edit:
If you want know what Columns names there a re from your table I believe you can use DESC TableA. Then you get a list a column names. You can use those to compaire against another list, for example from TableB.

Include table name in column from select wildcard sql

Is it possible to include table name in the returned column if I use wildcard to select all columns from tables?
To explain it further. Suppose I want to join two tables and both tables have the column name “name” and many other columns. I want to use wildcard to select all columns and not explicitly specifying each column name in the select.
Select *
From
TableA a,
TableB b
Where
a.id = b.id
Instead of seeing two column with same name "name", could I write a sql to return one column name as "a.name" (or TableA.name) and one as "b.name"(or TableB.name) without explicitly putting the column name in select?
I would prefer a solution for mssql but other database could be a reference too.
Thanks!
You can use select a.*, ' ', b.* from T1 a, T2 b to make it more visible where columns from T1 end and columns from T2 begin.
You are basically joining two tables on the ID field, so you will only see one column labeled "ID", not two, because you are asking to see only those records where the ID is the same in table a and table b: they share the same id.
Try ...
SELECT 'TableA' AS 'Table', A.* FROM TableA A
WHERE A.id IN (SELECT id FROM TableB)
UNION
SELECT 'TableB' AS 'Table', B.* FROM TableB B
WHERE B.id IN (SELECT id FROM TableA)
ORDER BY id, [Table]

how to select fields from different db's with the same table and field name

I have two databases, for argument sake lets call them db1 and db2. they are both structured exactly the same and both have a table called table1 which both have fields id and value1.
My question is how do I do a query that selects the field value1 for both tables linked by the same id???
You can prefix the table names with the database name to identify the two similarly named tables. You can then use that fully qualified table name to refer to the similarly named fields.
So, without aliases:
select db1.table1.id, db1.table1.value1, db2.table1.value1
from db1.table1 inner join db2.table1 on db1.table1.id = db2.table1.id
and with aliases
select t1.id, t1.value1, t2.value1
from db1.table1 as t1 inner join db2.table1 as t2 on t1.id = t2.id
You may also want to alias the selected columns so your select line becomes:
select t1.id as id, t1.value1 as value_from_db1, t2.value1 as value_from_db2
This is T-Sql, but I can't imagine mysql would be that much different (will delete answer if that's not the case)
SELECT
a.Value1 AS [aValue]
,b.Value1 AS [bValue]
FROM
db1.dbo.Table1 a
INNER JOIN db2.dbo.Table1 b
ON a.Id = b.Id
Try something such as this.
$dbhost="server_name";
$dbuser1="user1";
$dbpass1="password1";
$dbname1="database_I";
$dbname2="database_II";
$db1=mssql_connect($dbhost,$dbuser1,$dbpass1);
mssql_select_db($dbname1,$db1);
$query="SELECT ... FROM database_I.table1, database_II.table2 WHERE ....";
etc. Sorry if this does not help.
There is an easy way in sql. Extend your syntax for FROM clause, so instead of using select ... from tablename, use
select ... from database.namespace.tablename
The default namespace is dbo.
You could use a union select:
Simple example:
select "one" union select "two";
This will return 2 rows, the first row contains one and the 2nd row contains two. It is as if you are concatenating 2 sql quires, the only constant is that they both must return the same number of columns.
Multiple databases:
select * from client_db.users where id=1 union select * from master_db.users where id=1;
In this case both users databases must have the same number of columns. You said they have the same structure, so you shouldn't have a problem.