Inserting data into a table(mutliple columns) which has primary key from another data which has data except primary key - sql

I have a table that has 3 columns ID(Primary Key), Name, City.
I need to import data from another table that has only Name and City.
I can write insert into table 1(Name, City) select Name, City from table2.
But then I need ID in table 1 which needs to be inserted using a sequence.
I tried this:
insert into table1(ID, Name,City) values(seq.nextval, select distinct name, city from table2). But I am receiving an error saying an insufficient number of values.
I am trying it in SQL Oracle. Can someone please help me with this?

You are mixing the insert ... values and insert ... select syntax.
You edited your question to include distinct, implying you have duplicate name/city pairs that you want to suppress; but neither version gets the error you reported. If you don't have duplicates then you can just do:
insert into table1(ID, Name,City)
select seq.nextval, name, city from table2;
If you do have duplicates then you can't just add the distinct keyword, but you can use a subquery:
insert into table1 (id, name, city)
select seq.nextval, name, city
from (
select distinct name, city
from table2
);
db<>fiddle
You could also set the ID via a trigger. If you we're on a recent version you could use an identity column instead - but you tagged the question with Oracle 11g, where those are not available.

Related

SQL On Delete Trigger

I am trying to create a trigger that when a row is deleted from a table it gets inserted in another table:
1 Create Or Replace Trigger cancel
2 After Delete
3 On OrderTable
4 For EACH ROW
5 Begin
6 Insert Into CancelledOrders Values (:old.acctNum, age, phone)
7 From OrderTable Natural Join Customer
8 Where acctid = :old.acctNum AND menuid = :old.menuNum;
9 End;
10 /
11 Show Errors;
I want to grab the acctNum, age, and phone. The acctNum is from the Order table but the age and phone is from the Customer table. Therefore I join the two tables (on the acctid key). So the joined result will look like this:
acctNum Age Phone
I get this error when I try to compile the Trigger:
2/2 PL/SQL: SQL Statement ignored
3/2 PL/SQL: ORA-00933: SQL command not properly ended
Does anyone know the problem?
EDIT:
Table Structure:
OrderTable: AcctNum MenuNum startOrder endOrder
Customer Table: AcctNum age phone
You're mixing the values and select (subquery) syntax, which are for different things. You can insert from a query that uses a value from the :old pseudorecord and values from the customer table:
Insert Into CancelledOrders -- (acctNum, age, phone)
Select :old.acctNum, age, phone
From Customer
Where acctNum = :old.acctNum;
It's better to specify the columns in the target table as part of the insert clause (I've left that commented out in case the names are different). You also don't want (or need) to requery the table the trigger is against; you already have the data you need, and it will get a mutating-table error in some circumstances. So no join is needed.
Your insert statement is incorrect. You need to specify the columns you want to select in the tables.
Add the select clause to your insert statement. Also, removed the values keyword and specify column names:
Insert Into CancelledOrders (acctNum, age, phone)
Select :old.acctNum, age, phone
From OrderTable Natural Join Customer
Where acctid = :old.acctNum AND menuid = :old.menuNum;

Oracle SQL - Insertion with subquery returning multiple rows

I've an issue with a n-n relationship while trying to insert in the "middle table".
The goal is to associate Commune and ZipCode (in France, a Commune is a city, and the city name can have multiple ZipCode because there are commune with the same name. But not in the same place)
And a ZipCode can handle multiple City, here is my n-n relationShip.
So here is the request i use :
INSERT INTO FR(IDCODEPOSTAL, IDCOM_SIM)
VALUES
('24209 CEDEX', (SELECT DISTINCT IDCOM_SIM FROM COMMUNE WHERE NCCENR='Creysse'));
But here the SELECT returns 2 rows. I've read much but I didn't find a way to deal with this.
I'm not sure what you are trying to achieve, but usually you'd use an INSERT ... SELECT (without the VALUES) to insert multiple rows with a single statement:
INSERT INTO FR
(IDCODEPOSTAL, IDCOM_SIM)
VALUES
SELECT '24209 CEDEX', IDCOM_SIM
FROM COMMUNE
WHERE NCCENR='Creysse';
If you however want to insert only a single row, you need to make sure the sub-select returns only one. This is usually done using an aggregate function such as max()
INSERT INTO FR
(
IDCODEPOSTAL,
IDCOM_SIM
)
VALUES
(
'24209 CEDEX',
(SELECT max(IDCOM_SIM) FROM COMMUNE WHERE NCCENR='Creysse')
);

oracle unique constraint

I'm trying to insert distinct values from one table into another. My target table has a primary key studentid and when I perform distinct id from source to target the load is successful. When I'm trying to load a bunch of columns from source to target including student_id, I'm getting an error unique constraint violated. There is only one constraint on target which is the primary key on studentid.
my query looks like this (just an example)
insert into target(studentid, age, schoolyear)
select distinct id, age, 2012 from source
Why does the above query returns an error where as the below query works perfectly fine
insert into target(studentid)
select distinct id from source
help me troubleshoot this.
Thanks for your time.
In your first query you are selecting for distinct combination of three columns ie,
select distinct id, age, 2012 from source
Not the distinct id alone. In such case there are possibility for duplicate id's.
For example, Your above query is valid for this
id age
1 23
1 24
1 25
2 23
3 23
But in your second query you are selecting only distinct id's
select distinct id from source
So this will return like,
id
1
2
3
In this case there is no way for duplicates and your insert into target will not
fail.
If you really want to do bulk insert with constrain on target then go for
any aggregate functions
select id, max(age), max(2012) group by id from source
Or if you dont want to loose any records from source to target then remove your constraint on target and insert it.
Hope this helps

SQL 'simple' query syntax error - help!

My query returns a syntax error:
Invalid object name 'table.clientinfo'.
Here is my query:
INSERT table.clientinfo (name, addr, entry, affiliate )
SELECT name, addr, entry, affiliate FROM table.clientinfo WHERE product = 5
Is the error due to the insert function not finding 'clientinfo' as it does not exist.
Can anybody give me the correct syntax to create the table first before populating it from the select function?
You want CREATE TABLE
CREATE TABLE clientinfo (
name VARCHAR(100)
addr VARCHAR(100)
entry VARCHAR(100)
affiliate VARCHAR(100)
);
with specific types/sizes for your app. You might want to indicate foriegn and primary keys, constraints etc too
In SQL Server, if you want to select and insert into a new table, use this syntax:
SELECT name, addr, entry, affiliate
INTO (new table name)
FROM [table.clientinfo]
WHERE product = 5
You need to SELECT .... INTO and you need to make sure to use proper table names.
If you table name really has a dot in it (really really bad practice!), then you MUST put that table name in square brackets: FROM [table.clientinfo]
Also, when doing SELECT .. INTO ... you cannot select from an existing table and insert into the same existing table - you need to use a new table name for your destination table.
You should use
INSERT INTO [tablename] (field1, field2, ... , fieldx)
SELECT ...
Or if you want to create the other data directly:
SELECT field1, field2, ... , fieldx
INTO newTable
FROM oldtable
WHERE ....

Normalizing a table, from one to the other

I'm trying to normalize a mysql database....
I currently have a table that contains 11 columns for "categories". The first column is a user_id and the other 10 are category_id_1 - category_id_10. Some rows may only contain a category_id up to category_id_1 and the rest might be NULL.
I then have a table that has 2 columns, user_id and category_id...
What is the best way to transfer all of the data into separate rows in table 2 without adding a row for columns that are NULL in table 1?
thanks!
You can create a single query to do all the work, it just takes a bit of copy and pasting, and adjusting the column name:
INSERT INTO table2
SELECT * FROM (
SELECT user_id, category_id_1 AS category_id FROM table1
UNION ALL
SELECT user_id, category_id_2 FROM table1
UNION ALL
SELECT user_id, category_id_3 FROM table1
) AS T
WHERE category_id IS NOT NULL;
Since you only have to do this 10 times, and you can throw the code away when you are finished, I would think that this is the easiest way.
One table for users:
users(id, name, username, etc)
One for categories:
categories(id, category_name)
One to link the two, including any extra information you might want on that join.
categories_users(user_id, category_id)
-- or with extra information --
categories_users(user_id, category_id, date_created, notes)
To transfer the data across to the link table would be a case of writing a series of SQL INSERT statements. There's probably some awesome way to do it in one go, but since there's only 11 categories, just copy-and-paste IMO:
INSERT INTO categories_users
SELECT user_id, 1
FROM old_categories
WHERE category_1 IS NOT NULL