Moving data between tables on a specific condition - sql

I have two tables. In table Order, I have a column named customer_name. I am going to create a column named customer_id and customer_name is going to be dropped.
Before I drop that column, we have to look at the table Customer. Customer has one column name that matches the customer_name from Order. I want to find the SQL syntax that will let me move the id from Customer into the customer_id in Order, on the condition that Order.customer_name = Customer.name.
I am trying to use postgresql and have to learn how to use that, but even using regular SQL I have not found the solution yet.
I have tried:
ALTER TABLE Order
SELECT INTO customer_id
id from Customer
WHERE Order.customer_name = Customer.name;
and
INSERT INTO Order (customer_id)
SELECT id
FROM Customer
WHERE Order.customer_name = Customer.name;
I am getting a syntax error.
Is there another way I should write the condition? Or is it because of pgadmin and I need to write some other way?

You seem to want something like this:
ALTER TABLE Orders ADD customer_id INT;
UPDATE Orders
SET customer_id = c.id
FROM Customers c
WHERE o.customer_name = c.name;
Note: After doing this, you should check that all orders have a valid id. Then you may need to clean up records afterwards where the names do not match.

Related

How to get unique customer names those have different IDS

I am working with a table that contains Account_No as unique ID, Customer_Name, Building_Name. The table below is an example:
It can be seen for few cases there are same customer name and same building however different Account_No. I need to remove duplicate names even though they have unique Account_No. Building_Name and Customer_Name are ties together. For example "William----Science City" and "William-----River Club" should be count as two customers since they are residing in different buildings. The result table should look as below;
I need to use SQL for creating the resulting table. Kindly use Customer Table as the reference for SQL query. Thanks
Select Min(Account_No) As Account_No
,Customer_Name,Building_Name
From Customer_Table
Group By Customer_Name, Building_Name

Join 2 tables based on column name present in a table row

I have a table called Target where I have 5 columns:
ProductLevel
ProductName
CustomerLevel
CustomerName
Target
In another table called Products I have 3 columns:
ProductId
ProductCategory
ProductBrand
In the 3rd table called Customer I have 3 columns:
CustomerID
CustomerName
SubCustomerName
Is there a way to do a dynamic join where I select the column I will use in the JOIN based on the value that I have in the 1st table?
Example: If in the first table I have Category in ProductLevel, I'll join the table product using ProductCategory field. If I have Brand, I'll join using ProductBrand... The same happens with Customer table.
PS: I'm looking for a way to create it dynamically in a way I can add new columns to that tables without changing my code, then in the future I can have ProductSegment column in Product Table and Segment as a value in ProductLevel in Target table.
Yes, like this:
SELECT * FROM
Target t
INNER JOIN
Product p
ON
(t.ProductLevel = 'Category' AND t.??? = p.ProductCategory)
OR
(t.ProductLevel = 'Brand' AND t.??? = p.ProductBrand)
You didn't say which column in Target holds your product category/brand hence the ??? in the query above. Replace ??? with something sensible
PS; you can't do as you ask in your PS, and even this structure above is an indicator that your data model is broken. You can at least put the code in for it now even if there are no rows with t.ProductLevel = 'Segment'
Don't expect this to perform well or scale.. You might be able to improve performance by doing it as a set of UNION queries rather than OR, but you may run into issues where indexes aren't used, crippling performance

Oracle SQL Update a column based on another table but based on a date

Learning SQL so please forgive me.
I have a table that holds many accounts(and sub accounts) and another table that holds many orders they are custom tables taken from different databases.
What I am trying to do is update order_amt on the account table with the order_val value from the orders table but if there are more than one order with that account I want the order amount from the earliest order date only.
Account Table
Acc _Num..........Comp_Name.......Order_Amt.......Int_Id
123456789-1.....ABC Ltd.......................................123456789
123456789-2.....ABC Ltd.......................................123456789
987654321-1.....Xyz Ltd.........................................987654321
987654321-2.....Xyz Ltd.........................................987654321
Orders Table
Order_Num.....Order_Dt.....Order_Val.....Acc_num
1......................01/01/13......£20.00...........123456789
2......................01/01/14......£10.00...........123456789
3......................01/01/10......£100.00..........987654321
4......................01/01/11......£200.00..........987654321
So the order_amt for accounts 123456789-1 & 2 = £20.00 and from 987654321-1 & 2 would be £100.00.
UPDATE accounts a
SET a.order_amt =
(
SELECT order_val
FROM orders o
WHERE a.int_id = o.acc_num
AND EXISTS
(
SELECT MIN(order_dt)
FROM orders oa
WHERE o.order_num = oa.order_num
);
I am getting a few errors including the error that more than one row returned? Could anyone please help me?
kind Regards
Eden
I think you need something like this:
UPDATE accounts a
SET a.order_amt =
(
SELECT order_val
FROM orders o
WHERE a.int_id = o.acc_num
GROUP BY order_val
HAVING order_dt = MIN(order_dt);
);
Create a FK on the column account_number inside of the orders table and have it reference the auto-increment account id of the accounts table.
Then as Roger suggest, with the slight modification of the column int_id AND a modification of the HAVING clause
UPDATE accounts a
SET a.order_amount =
(
SELECT order_value
FROM orders o
WHERE a.account_number = o.account_number
GROUP BY order_value
HAVING MIN(order_date)
)
This will not fix the error that is occurring with more than one row being returned though since there are multiple orders with the same account id attached to them. You will need to be more specific about how what you are needing. Do you want the average of all order amounts to equal the order value in the accounts table? Or maybe the MAX/MIN value?

SQL, Select from table A and use result ID to loop though table B?

I have a windows server running MS-SQL 2008.
I have a customer table that I need to select the id's of all customers that are Active, On Hold, or Suspended.
get all customers that are Y= current active customer H=on hold S=Suspended
select id from customer where active = 'Y';
the above statement worked fine for selecting the ID's of the affected customers.
I need to use these results to loop though the following command in order to find out what rates all the affected customers have.
get all rates for a customer
select rgid from custrate where custid = [loop though changing this id with results from first statement];
the id from the customer table coincides with the custid from the custrate table.
So in the end I need a list of all affected customer id's and what rgid's(rate group(s)) they have.
SQL isn't about loops in general and instead you should think in terms of joins.
select customer.id, custrate.rgid, customer.active
from customer
inner join custrate
on customer.id = custrate.custid
where active in ('Y', 'H', 'S")
order by customer.active, customer.id
would be a starting point to think about. However, that is just a wild guess as the schema was not specified nor the relations between the tables.

How can I apply the LIMIT statement in a SQLite query to a specific side of a join?

Here's my requirement:
I have 2 tables, orders and orderContents. For each row in the orders table, there are a certain number of rows that contain description of the order. id column serves as foreign key.
What I want is to get all the details for each order (details from orderContents, including id column from orders table) table, but limit no. of results based on common column (foreign key, id)
Problem is that it limits orderContents rows, instead of limiting order rows.
How can I achieve desired effect?
EDIT: Updating tables and desired result set
Orders table:
OrderContents table:
Desired result on limiting number of records to 2:
I'm assuming you are trying to say that you want the results from both tables but only for the first X orders. If so, try this:
SELECT OC.*, O.* FROM OrderContents OC
INNER JOIN (SELECT *
FROM Orders
ORDER BY ID
LIMIT 2) O ON O.ID=OC.ID