CREATE TABLE failed ORA 00957 Duplicate column name - sql

As I tried to create new table from existing 2 table with specific column name in oracle.
I tried below code
CREATE TABLE D_T1
AS
SELECT a.col1, a.col2, a.col3, a.col4, a.col5, b.col6, b.col7, b.col8
FROM db1.table1 a INNER JOIN db1.table2 b
ON (a.col1 = b.colNum AND a.col2 = b.colnum1)
But I get error
CREATE TABLE failed ORA 00957 Duplicate column name
Can anyone help?

Ignoring the other errors you seem to have introduced by retyping the code, you've shown that you do have a duplicate column, which is what the error is telling you:
a.VALIDFLAG, b.VALIDFLAG
You seem to be under the impression that the table (alias) prefix makes the column names in the projection unique. They do not. The table prefix tells Oracle which table to get the column value from (unless you're using the using join syntax, which you are not). If the column appears in two tables you have to prefix the column name with the table. If you want the value from both tables you have to prefix both of them.
With a simple query then referring to both table columns without column aliases is OK, but something trying to consume the result set might struggle. This is fine:
select a.dummy, b.dummy
from dual a
join dual b on b.dummy = a.dummy;
DUMMY DUMMY
------- -------
X X
But notice that both columns have the same heading. If you tried to create a table using that query:
create table x as
select a.dummy, b.dummy
from dual a
join dual b on b.dummy = a.dummy;
You'd get the error you see, ORA-00957: duplicate column name.
If you alias the duplicated columns then the problem goes away:
create table x as
select a.dummy as dummy_a, b.dummy as dummy_b
from dual a
join dual b on b.dummy = a.dummy;
So in your case you can alias those columns, if you need both:
..., a.VALIDFLAG AS validflag_a, b.VALIDFLAG AS validflag_b, ...

To be completely honest, that query is a mess. You've got several errors in your SQL statement:
CREATE TABLE AS SELECT
The table name is missing - this should be
CREATE TABLE my_new_table AS SELECT
to create a new table named my_new_table.
a.ALIDFLAG,b,VALIDFLAG,
I've got a suspicion that this should really be a.VALIDFLAG instead of a.ALIDFLAG. Also, you need to replace b,VALIDFLAG with b.VALIDFLAG.
SELECT a.BILLFREQ a.CDHRNUM,
You're missing a comma after a.BILLFREQ - this is a syntax error.
a.A‌​GNYCOY,a.AGNTCOY
There's the culprit - you're selecting the same column twice. Get rid of the second one.
EDIT Actually, the names are different, so this isn't the cause of the error (unless you've mistyped your query in the comment instead of copy& paste).
To debug this kind of errors, try to
format your SQL statement in a readable way
comment out everything but one column, run the statement and ensure it works
add one column
repeat until you find the error or you've added all columns
2ND UPDATE
With the updated query, the error is here:
a.VALIDFLAG,
b,
VALIDFLAG,
You have two columns named VALIDFLAG - use an alias for one of these, and it should work.

ORA-00957: duplicate column name
The only reason for that error in your CTAS statement is that you have similar column name in the SELECT statement. Though you might be referring to different table columns, but you did not use a column alias
Error reproduce:
Using the standard EMP and DEPT table.
SQL> CREATE TABLE D_T1 AS
2 SELECT a.deptno,
3 b.deptno
4 FROM emp A
5 INNER JOIN dept b
6 ON (a.deptno = b.deptno);
b.deptno
*
ERROR at line 3:
ORA-00957: duplicate column name
Workaround:
Use proper alias:
SQL> CREATE TABLE D_T1 AS
2 SELECT a.deptno e_deptno, --add column alias
3 b.deptno d_deptno --add column alias
4 FROM emp a
5 INNER JOIN dept b
6 ON (a.deptno = b.deptno);
Table created.

Edit as per new input from OP.
You have some syntax error in your query. Corrected those. I also checked for duplicate columns. There are none. Now run this and let me know if you still get same error.
CREATE TABLE D_T1 AS SELECT
a.B, a.C,a.C, a.C, a.C,a.J, a.O,
a.P,a.P,a.S,a.S,a.R,a.B,
a.S,a.S,b.A,b.C,b.C,b.I, b.M,
b.P,b.P,b.S,b.S,b.S,b.Z,b.Z,a.C,
a.CH‌​,a.G,b,V,b.T,a.C,a.C,a.C,
a.A,a.A‌​Ga.AG
FROM tbl1 a JOIN tbl2 b
ON (a.C= b.C AND a.C1= b.C1)

Related

Why am I getting the error: "Ambiguous column" in my query?

In this query I inserting records into a new empty table I created. These records are derived from another table where I am left joining that table to itself, in order to output records that are not included in the recent table that is appended on top of an older table. So basically it outputs records that were deleted.
CREATE DEFINER=`definer` PROCEDURE `stored_procedure_name`()
MODIFIES SQL DATA
SQL SECURITY INVOKER
BEGIN
START TRANSACTION;
INSERT INTO exceptions_table (
`insert_date`,
`updated`,
`account_number`,
`id_number`)
SELECT
`insert_date`,
`updated`,
`account_number`,
`id_number`
FROM original_table ot1
LEFT JOIN original_table ot2
ON ot1.`account_number` = vdcaas2.`account_number`
AND ot2.`insert_date` = '2022-12-20'
WHERE ot1.`insert_date` = '2022-12-10'
AND ot2.`account_number` IS NULL;
COMMIT;
END
I get an error stating: "SQL Error: Column "insert_date" in field list is ambiguous.
I'm not sure why because I have specified which table I am grabbing "insert_date" from when INSERTING and when SELECTING and JOINING..
Every row in your query has two columns called insert_date: one from the table you've aliased as "ot1", and one from the table (as it happens, the same table) you've aliased as "ot2".
The database system doesn't know which one you want, so you have to tell it by writing either "ot1.insert_date" or "ot2.insert_date", just as you do elsewhere in the query:
... ot2.`insert_date` = '2022-12-20'
...
... ot1.`insert_date` = '2022-12-10'
The same is true of the other columns you've listed to select.
You need to change this
SELECT
`insert_date`,
`updated`,
`account_number`,
`id_number`
to this
SELECT
ot1.`insert_date`,
ot1.`updated`,
ot1.`account_number`,
ot1.`id_number`
or this
SELECT
ot2.`insert_date`,
ot2.`updated`,
ot2.`account_number`,
ot2.`id_number`
or some combination
Issue
SQL Error: Column "insert_date" in field list is ambiguous error means that the query is trying to reference the "insert_date" column from both tables, ot1 and ot2.
Try the following:
SELECT
ot1.`insert_date`,
ot1.`updated`,
ot1.`account_number`,
ot1.`id_number`
Also, you have a typo in your query:
ON ot1.`account_number` = vdcaas2.`account_number` -> ON ot1.`account_number` = ot2.`account_number`

Using a JOIN within a UNION ALL view creation

I am creating a view merging two tables with some similar fields and some dissimilar fields. I have this 95% working but there is one field from table A that matches up with a field from table B but only if you use that field from B as a join to pull a field from table C. The only part of the code below that isn't working is the JOIN. I could just put both of the fields in and do the logic to get provider_id from the ehruser_id in the model, but I feel like it should be doable in the SQL and I just don't have the knowledge to get that last bit working yet
DROP VIEW IF EXISTS vunifiedschedule CASCADE;
CREATE VIEW vunifiedschedule AS
SELECT
schedule_block.id as vid,
schedule_block.reason as vblock_reason,
NULL as vappointment_reason_id,
schedule_block.when_ts as vwhen,
schedule_block.deleted_ts as vdeleted_when,
schedule_block.placeofservice_id as vlocation_id,
schedule_block.duration as vduration,
true as vappointment_book,
schedule_block.note as vnote
FROM schedule_block
LEFT JOIN ( SELECT id FROM provider) as vprovider_id ON provider.ehruser_id = schedule_block.ehruser_id
UNION ALL
SELECT
appointment.id AS vid,
NULL as vblock_reason,
appointment.appointmentreason_id AS vappointment_reason_id,
appointment.appt_when AS vwhen,
appointment.deleted_when AS vdeleted_when,
appointment.location_id AS vlocation_id,
appointment.visit_length AS vduration,
appointment.appointment_book as vappointment_book,
appointment.note AS vnote,
appointment.provider_id as vprovider_id
FROM appointment
The error I get is
ERROR: missing FROM-clause entry for table "provider"
LINE 14: ...ELECT id FROM provider) as vprovider_id ON provider.e...
The error is pretty clear. You have no provider. I think you intend:
FROM schedule_block LEFT JOIN
( SELECT id FROM provider) vprovider_id
ON vprovider.ehruser_id = schedule_block.ehruser_id
--------^
However the subquery is unnecessary:
FROM schedule_block LEFT JOIN
provider
ON provider.ehruser_id = schedule_block.ehruser_id
1st select stmt of view has 9 columns but 2nd select stmt has 10 columns. This view will error with message "Query block has incorrect number of result columns
You selected 9 columns from the first table and 10 from the second, when using union you must have the same number of columns in both queries and the type columns selected must match.

An object or column name is missing or empty GEOMETRY

I'm trying to do a geometric union but it's not working
select b.[Region],geometry::UnionAggregate(geom.MakeValid()) into dbo.DRShape
from [dbo].[departements2] a join [dbo].[BM_REGIONFR] b
on a.[code_insee] = b.[dep_2]
group by b.Region
Msg 1038, Niveau 15, État 5, Ligne 1
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.
You are trying to create a table using SELECT INTO, the table needs a column name for each column. Your second column result is missing an alias (that will turn into a column name).
select
b.[Region],
geometry::UnionAggregate(geom.MakeValid()) AS Geo -- Add Alias!!
into
dbo.DRShape
from [dbo].[departements2] a join [dbo].[BM_REGIONFR] b
on a.[code_insee] = b.[dep_2]
group by b.Region
If you comment the INTO dbo.DRShape and you see that your query runs OK, means that the problem is the creation of your new table.

SQL Compare 2 columns from 2 tables to complete another column

The tables have the following columns:
Table A:
TIN,
Fee_Sched,
Effective_Date
Table B:
TIN,
Fee_Sched,
Fee_Sched_Eff
TableB.Fee_Sched & TableB.Fee_Sched_Eff are currently blank
This is what I want to do:
I want to compare the two TIN columns and when there is a match, I want the corresponding results from TableA.Fee_Sched to print in TableB.Fee_Sched and the results from TableA.Effective_Date to print in TableB.Fee_Sched_Eff
I am assuming I would use a join or union and possibly an IF statement (if tableA.TIN = tableB.TIN, then print tableA.fee_sched and TableA.Effective_Date). But, I am not sure how I designate which column the results should stored in or how to organize the code correctly.
**Example:**
Table A
TIN Fee_Sched Effective_Date
123 ABCEDF 1/1/2011
456 ZYXABC 9/9/2009
TABLE B
TIN Fee_Sched Fee_Sched_Eff
123 blank blank
**Results:**
TABLE B
TIN Fee_Sched Fee_Sched_Eff
123 ABCEDF 1/1/2011
I've tried this:
Insert INTO dbo.TableB (Fee_Sched, Fee_Sched_Eff)
SELECT Fee_Sched, Effective_Date
FROM dbo.TableA Where dbo.TableA.TIN = dbo.TableB.TIN;
But, I get this error:
Msg 4104, Level 16, State 1, Line 3 The multi-part identifier
"dbo.TableB.TIN" could not be bound.
There are four basic verbs/actions in SQL:
select retrieves data
insert adds data
delete removes data
update changes data.
Update is the one you need to use. With MS SQL you can achieve your desired result using this update query:
update b
set b.Fee_Sched = a.Fee_Sched, b.Fee_Sched_Eff = Effective_Date
from TableB b
join TableA a on a.TIN = b.TIN
Well, first things first: if you want to modify table B, you are looking for an UPDATE command. Also, notice that you can use a SELECT inside the UPDATE statement, and you can reference the "outer" table from inside the SELECT. This should do the trick:
update B set B.fee_sched = (SELECT fee_sched FROM A WHERE A.TIN=B.TIN)
Finally, remember to always post which RDBMS you are using, as there may be differences on what you can write for each of them (Microsoft SQL, Oracle, MySQL?)

solution for ORA-00933

I'm tring to use join but facing this issue. I've pasted my query
select count(*) from table_a inner
join table_b on table_a.number = table_b.number
left outer join table_c on table_a.id = table_c.id
and table_a.number = table_c.number
order by number;
pls let me know what is wrong in the query...
-Vinod
Are you executing this query as part of an INSERT or DELETE?
If so, remove the ORDER BY. It's not needed anyway.
Error: ORA-00933: SQL command not
properly ended
Cause: You tried to
execute an SQL statement with an
inappropriate clause.
Action: The
options to resolve this Oracle error
are:
You may have executed an INSERT
statement with an ORDER BY Clause. To
resolve this, remove the ORDER BY
clause and re-execute the INSERT
statement. For example, you tried to
execute the following INSERT
statement:
INSERT INTO supplier (supplier_id,
supplier_name) VALUES (24553, 'IBM')
ORDER BY supplier_id;
You can correct the INSERT statement
by removing the ORDER BY clause as
follows:
INSERT INTO supplier (supplier_id,
supplier_name) VALUES (24553, 'IBM');
You may have tried to execute a DELETE
statement with an ORDER BY Clause. To
resolve this, remove the ORDER BY
clause and re-execute the DELETE
statement. For example, you tried to
execute the following DELETE
statement:
DELETE FROM supplier WHERE
supplier_name = 'IBM' ORDER BY
supplier_id;
You can correct the DELETE statement
by removing the ORDER BY clause as
follows:
DELETE FROM supplier WHERE
supplier_name = 'IBM';
How did you execute this query?
In Oracle SQL, there's no such thing as a statement separator like ";". That one is only used in PL/SQL and some tools allow you to put more than one statement in a file/editor, when you separate them with ";". Only so that they can execute them separately.
Long story short: remove the ";" and try again.
Oh and next time, tell us how you ran the query. We have to check our crystal balls to guess what your problem is.
You cannot order by a value which cannot be included in the result set. your result set aggregates multiple rows, each with its own value of NUMBER, into a single row. therefore the order by does not make logical sense. In this case your query only returns one row so ORDER BY is irrelevant.
When you transcribed your query to the anodyne test case you present here you inadvertently corrected it. Well, you introduced an ORA-00918 bug but once that is fixed the code runs fine...
SQL> create table table_a (col_1 number, id number)
2 /
Table created.
SQL> create table table_b (col_1 number)
2 /
Table created.
SQL> create table table_c (col_1 number, id number)
2 /
Table created.
SQL>
SQL>
SQL> select count(*) from
2 table_a inner join table_b on table_a.col_1 = table_b.col_1
3 left outer join table_c on table_a.id = table_c.id
4 and table_a.col_1 = table_c.col_1
5 order by col_1
6 /
order by col_1
*
ERROR at line 5:
ORA-00918: column ambiguously defined
SQL> select count(*) from
2 table_a inner join table_b on table_a.col_1 = table_b.col_1
3 left outer join table_c on table_a.id = table_c.id
4 and table_a.col_1 = table_c.col_1
5 order by table_a.col_1
6 /
COUNT(*)
----------
0
SQL>
Note: I have subsituted COL_1 for NUMBER as a column name. I don't think that's your problem, because using NUMBER unescaped in the query would hurl ORA-1747 not ORA-00933.
So, let's rule out the obvious: are you running on an ancient version of Oracle which doesn't support the ANSI join syntax, that is 8i or older?