I'm trying to add an age column to a database (junecustomers) using a DOB column from an existing database (customerdata).
I have a matching firstname, lastname, and customerid column in both data sets. In the customerdata data set, I have the DOB column that I want to use to calculate the age. Is this correct?
select * from junecustomers
left join customerdata
on junecustomers.customerid = customerdata.customerid
alter table (junecustomers)
add select
trunc(months_between(sysdate, dob)/12) Age from customerdata
Note: the customerdata database has multiple entries for some of the customers but the junecustomers database has only one entry per customer.
You need to run two scripts, one to add the column and one to update the data, e.g.:
ALTER TABLE junecustomers
ADD COLUMN age INT;
UPDATE junecustomers jc
SET jc.age = (SELECT trunc(months_between(sysdate, dob)/12) FROM customerdata
WHERE customerid = jc.customerid LIMIT 1);
Related
I am trying to to split a table into two table and want to add the reference (foreign key) of one table to another
For Example lets say there are is a table called customer table and an Column in it called Group Name has repetitive data which goes against data normalization, so I want to split the table on that column, which would be to replace that Group name Column with GroupID column
NOW form a new table with 2 column GroupID and Group Name and insert distinct Group values into GroupName column, with an auto-incrementing GroupID which will be the Primary key in the group table, and be refrenced in Customer table to act as a foreign key
Now the main question is how to Insert those Autoincremented GroupID of 'GROUP TABLE' into groupID of the customer Table or how do You Insert Foreign Keys into Customer Table According to the Main table
The customerTable With GroupID and customerTable With Customer_Group are two diffrent table
UPDATE ch03.customerd
JOIN ch03.group gr ON customer.Customer_Group = gr.Group_Name
SET customerd.Group_ID = gr.Group_id
WHERE customerd.Customer_id = customer.Customer_id;
update ch03.customerd set Group_ID =
(select gr.Group_id
from ch03.customer as co
join ch03.group as gr on co.Customer_Group = gr.Group_Name)
where customerd.Customer_id = customer.Customer_id;
this is what i have tried and isn't working
If all data except group_id is already transferred then
UPDATE new_customer_table nc
JOIN old_customer_table oc ON nc.customer_id = oc.customer_id
JOIN new_group_table ng ON oc.customer_group = ng.group_name
SET nc.group_id = ng.group_id
If new tables are empty yet then
INSERT INTO new_group_table (group_name)
SELECT DISTINCT customer_group
FROM old_customer_table;
INSERT INTO new_customer_table (customer_id, .. , customer_age, group_id)
SELECT oc.customer_id, .. , oc.customer_age, ng.group_id
FROM old_customer_table oc
JOIN new_group_table ng ON oc.customer_group = ng.group_name;
PS. If customer_group in old table is not defined as ENUM / have no CHECK constraint which checks entered values for validity then I recommend to execute INSERT INTO new_group_table .. firstly and check the values inserted carefully. If some misprintings will be found then you need to edit source data before, then truncate new_group_table and repeat - until all group names are correct.
I want to insert data from a table and i don't want the same date data again imported on my destination table.
For example- I have date as a column on my source and destination both table and i dont want same date data in my destination table. the date column is same on both table, and number of columns are also same in both tables.
How can i achieve this?
Best way is to use NOT EXISTS as follows:
INSERT INTO destination_table
select *
from source_table s
where not exists
(select 1 from destination_table d where d.date = s.date)
filter those days and insert
INSERT INTO destination_table
select a.* from source a
where a.date not in ( select date from destination_table)
You can create the destination table as follows:
CREATE TABLE Destination (
ID int NOT NULL,
Property1 PropertyType,
Property2 PropertyType,
etc.....
UniqueDate DATE,
UNIQUE (UniqueDate)
);
Remember to substitute PropertyX and PropertyType with your own properties and types, as well as rename UniqueDate
This code will set a UNIQUE constraint on your Date Column.
I have two tables:
Persons (PersonID, LastName, FirstName)
Orders (O_Id, OrderNo, P_Id)
Orders.P_Id should have values from Persons.PersonID.
I am trying to do an insert on Orders to insert the P_Id into orders but I want it to match a value in my Persons table and also my Orders table so I can link them up and allow the P_id to be linked to the order.
I have tried this below? not sure what the best way to do this would be?
INSERT INTO Orders (P_Id)
SELECT PersonID FROM Persons
WHERE PersonID='1'
UNION ALL
SELECT O_Id FROM Orders
WHERE O_Id ='1';
Edit:
I have tried UNION ALL but it doesn't add them on the same line here is my sql fiddle which shows what is happening:
http://sqlfiddle.com/#!9/30a71/1
anyone help?
I think you want to UPDATE (not INSERT):
UPDATE ORDERS SET
P_Id = 1
WHERE O_Id = 1;
See SQLFiddle
I think what you're actually trying to achieve is not through the form of an INSERT, but an UPDATE:
Try this:
UPDATE Orders
SET P_ID = (SELECT PersonID From Persons WHERE PersonID = 1)
WHERE O_ID = 1
You can't "INSERT" a value into an existing row with a INSERT command. For that reason the UPDATE command exists.
The INSERT is useful only when creating a row in the table. For all other scenarios, when you are trying to populate a column with data, into an existing row, then you should use UPDATE.
The above query is basically a re-write of what you have, but since you already know the value of PersonID which you want to populate the P_ID column with, then you can simplify the query to:
UPDATE Orders
SET P_Id = 1
WHERE O_Id = 1
Suppose I have a table with one column - called 'person' that contains a list of names. I want to find a specific person based off his index.
I tried using a sql variable to track each column index but the issue is - is that if I have a table of 5 records this will always output the 5th record.
SET #row_num = 0; SELECT #row_num := #row_num + 1 as row1 ,person FROM table;
SELECT row1 from table WHERE person = 'name'
I would recommend changing your database to add a second column for row_id. This is a fairly common practice. Then you can just use
SELECT * from table WHERE row_id = 3;
This will return the third row.
Another best possible way would be by means of a TEMPORARY TABLE as explained below
create a temp table
create temporary table temptab(ID INT NOT NULL AUTO_INCREMENT,Person VARCHAR(30))
Then insert data to temp table as
insert into temptab(Person) select Person from mytable
Then select the specific index person name from temp table like
select Person from temptab where ID = 5
Say I have two tables: orderinfo and customerinfo
They look like this:
orderinfo:
OrderID
CustomerID
OrderCustomerName
OrderCustomerAddress
customerinfo:
CustomerID
CustomerName
CustomerAddress
Both OrderID and CustomerID are unique. When an order is to be created, I need to copy the info from customerinfo to orderinfo at that time as the customer may change his information later.
I hope I can just use CustomerID to achieve this. How should I write the subquery? Thanks.
When you insert a new order, you can grab a "snapshot" of the customer data with the following simple INSERT... SELECT query syntax:
INSERT INTO orderinfo (CustomerID, OrderCustomerName, OrderCustomerAddress, status)
SELECT CustomerID, CustomerName, CustomerAddress, 'P'
FROM customerinfo
WHERE CustomerID = <customerid here>
This inserts a new order with the customer info at the exact time the order was placed.
This information will remain just as how it was inserted even if the customer updates his or her information in the customerinfo table because there aren't any cascade effects other than if the CustomerID changes (which it shouldn't, and even if it did change, it wouldn't change the "snapshot" data).
To update orderinfo with the current values for customer name and address based on a CustomerID, use an UPDATE JOIN:
UPDATE
orderinfo
JOIN customerinfo ON orderinfo.CustomerID = customerinfo.CustomerID
SET
OrderCustomerName = CustomerName,
OrderCustomerAddress = CustomerAddress
WHERE OrderID = <some_order_id>
This is useful if you want to "freeze" the customer information associated with a specific order, even if the customer later changes that information globally. If I understand correctly, that is your intent.
You can also do this with an AFTER INSERT trigger on the orderinfo table. Then you needn't execute a separate query:
CREATE TRIGGER update_order_cust_info AFTER INSERT ON orderinfo
FOR EACH ROW
BEGIN
UPDATE
orderinfo
JOIN customerinfo ON orderinfo.CustomerID = customerinfo.CustomerID
SET
NEW.OrderCustomerName = CustomerName,
NEW.OrderCustomerAddress = CustomerAddress
WHERE OrderID = NEW.OrderID
END
What you are looking for is
INSERT INTO orderinfo
(OrderID, CustomerID, OrderCustomerName, OrderCustomerAddress)
VALUES (
'12345',
'789',
(SELECT CustomerName FROM customerinfo WHERE CustomerID = '789'),
(SELECT CustomerAddress FROM customerinfo WHERE CustomerID = '789')
)
But i strongly advise a change in your database structure. What you try to do violates the Database Normalisation rules. Instead, read this article on Wikipedia on Slowly Changing Dimensions and implement it as such.