I am trying to create a sql table for orders. We have another table what has a primnary key of productID. When a customer creates an order it should list the orderID as well total and a foreignkey of productID. The issue I have is that it only allows 1 productID.
Is there a way for sql to add multiple foreign keys to the same row for the same item? If that makes sense?
I placed both tables here to try and show what I meant.
Your table structure only allows one product per order, because you've got a single productId column on the orders table.
To allow multiple products per order, I would create an orderItems table. Each orderItem has a different productId, and links back to the orders table via an orderId. Like this:
------------------------
orders table
------------------------
orderId (primary key)
orderDate
orderTotal
customerId (foreign key)
specialInstructions
-------------------------
orderItems table
-------------------------
orderItemId (primary key)
orderId (foreign key)
productId (foreign key)
quantity
-------------------------
products table
-------------------------
productId (primary key)
productTitle
productDescription
productPrice
I am designing a SQL database for sales person of a firm, where each customer will order multiple items from the firm. I want to store this order uniquely to the customer. Which will be linked to customer table.
Customer Table :
Cust_id
Cust_name
Cust_phone
Currently I am thinking of making a separate order table for each order
Order Table:
Product_id
Prod_quantity
Total_amt
but can't figure out how to link it back to customer. Or how to uniquely identify each order table.
I would have done it in NoSQL but data has to be locally stored in SQLite.
Customer may order multiple times so I should be able to identify current and previous orders
Do not create a separate table for each order! That's a very bad design. Relational tables aren't spreadsheets!
Have one table for the orders with a foreign key pointing to the customers. For the items of orders have a linking table with a foreign key to the order and another to the item. That's fairly standard thing (I'm pretty certain you'll find such a classic example in many tutorials about relational database design.). Something along the lines of:
CREATE TABLE customer
(id integer,
name varchar(64),
...
PRIMARY KEY (id));
CREATE TABLE product
(id integer,
name varchar(64),
...
PRIMARY KEY (id));
CREATE TABLE order
(id integer,
customer integer,
...
PRIMARY KEY (id),
FOREIGN KEY (customer)
REFERENCES customer
(id));
CREATE TABLE order_product
(order integer,
product integer,
amount integer,
...
PRIMARY KEY (order,
product),
FOREIGN KEY (order)
REFERENCES order
(id),
FOREIGN KEY (customer)
REFERENCES customer
(id));
(order might be a bad choice for a table or column name in some DBMS as it's also a keyword and thus required quoting. So probably chose something else. I used it just for the sake of clarity.)
I have problem with summing values... Tables are presenting like this:
create table clients
(
id_c INTEGER not null,
name VARCHAR2(20),
age INTEGER,
address VARCHAR2(20),
price number,
Primary key (id_c)
);
create table PRODUCTS
(
id_p NUMBER not null,
name_product VARCHAR2(30),
price NUMBER,
duration NUMBER,
primary key (id_p)
);
create table TRANSACTIONS
(
id_t NUMBER not null,
id_c NUMBER not null,
id_p NUMBER not null,
td_c NUMBER,
primary key (ID_t),
foreign key (ID_c) references CLIENTS (ID_c)
);
now i want to sum up all costs of products (translations.td_c) for each client (translations.id_c), and put that value to table clients into price row. The point is to take the same ID of client (ID_C) and sum up every row that have that ID_C in transactions table, sum up for that client every value of td_c, and put it into table clients to price column... I don't know how to do that, every time when i trying to make some UPDATE code, there are errors...
Try it with a subquery:
UPDATE clients
SET price = (SELECT sum(transactions.td_c)
FROM transactions
WHERE transactions.id_c = clients.id_c);
But your design is probably problematic. clients.price entirely depends on transactions and therefore shouldn't exist materialized like that.
I'll immediately go out of sync, if there are any changes in transactions. E.g., if you insert a new row into transactions for some customer "John" with an td_c of +100, the price for "John" in the clients table will be a 100 short until you update it again.
Consider using a view to have the price and the client data joined, always selecting the current price from transactions. E.g.:
CREATE VIEW clients_with_price
AS
SELECT c.id_c,
c.name,
c.age,
c.address,
s.price
FROM clients c
LEFT JOIN (SELECT sum(t.td_c) price,
t.id_c
FROM transactions t
GROUP BY t.id_c) s
ON s.id_c = c_id.c;
Then drop the price column in clients.
I am making a piece of invoicing software and I want it to save each individual invoice.
The user creates invoices by selecting a customer, as well as however many items are being billed to the customer. Seeing as most invoices will have multiple items, what is the best way to save them to the database without being incredibly redundant? I'm willing to rearrange my entire database if need be.
My tables look like this:
Customers Table:
Id / Primary key
FullName
Address
Phone
Items Table (a table of products offered):
Id / Primary key
ItemName
Price
Description
Invoices Table (saved invoices):
Id / Primary key
CustId / Foreign key is Id in Customer table
ItemId / Foreign key is Id in Item table
Notes
You need another table to store invoices (what you call Invoices now actually stores invoice items).
Customer
id
name
etc.
Item
id
name
etc.
Invoice
id
cust_id
date
InvoiceItem
id
inv_id
item_id
This is the classic way of modeling a many to many relationship using a junction table (i.e. InvoiceItem).
It looks like you will actually want a 4th table to join them. To normalize your data, only keep on each line things that are specific to that invoice
Invoices table
Id / Primary key
CustId / Foreign key is Id in Customer table
Notes
Invoice Items table
InvoiceId
ItemId
Consider this example schema:
Customer ( int CustomerId pk, .... )
Employee ( int EmployeeId pk,
int CustomerId references Customer.CustomerId, .... )
WorkItem ( int WorkItemId pk,
int CustomerId references Customer.CustomerId,
null int EmployeeId references Employee.EmployeeId, .... )
Basically, three tables:
A customer table with a primary key and some additional columns
A employee table with a primary key, a foreign key constraint reference to the customer tables primary key, representing an employee of the customer.
A work item table, which stores work done for the customer, and also info about the specific employee who the work was performed for.
My question is. How do I, on a database level, test if an employee is actually associated with a customer, when adding new work items.
If for example Scott (employee) works at Microsoft (customer), and Jeff (employee) works at StackOverflow (customer), how do I prevent somebody from adding a work item into the database, with customer = Microsoft, and employee = Jeff, which do not make sense?
Can I do it with check constraints or foreign keys or do I need a trigger to test for it manually?
Should mention that I use SQL Server 2008.
UPDATE: I should add that WorkItem.EmployeeId can be null.
Thanks, Egil.
Wouldn't a foreign key on a composite column (CustomerId, EmployeeId) work?
ALTER TABLE WorkItem
ADD CONSTRAINT FK_Customer_Employee FOREIGN KEY (CustomerId, EmployeeId)
REFERENCES Employee (CustomerId, EmployeeId);
You might be able to do this by creating a view "WITH SCHEMABINDING" that spans those tables and enforces the collective constraints of the individual tables.
Why do you want employeeId to be null int WorkItem? Maybe you should add another table to avoid that particular oddity. From what I can see the easiest thing to do is to add a unique constraint on employeeid in workItem, and maybe even unique on customerId if that is what you want.
A more general way to add constraints spanning many tables is to define a view that should always be empty, and add the constraint that it is empty.
What are you trying to model here?
You're a contracting agency or the like, and you have a bunch of contractors who are (for some period of time) assigned to a customer.
You're actually storing information about other company's employees (maybe you're providing outsources payroll services, for example).
In case (1), it looks like you have a problem with the Employee table. In particular, when Scott's contract with MS is up and he gets contracted to someone else, you can't keep the historical data, because you need to change the CustomerId. Which also invalidates all the WorkItems. Instead, you should have a fourth table, e.g., CustomerEmployee to store that. Then WorkItem should reference that table.
In case (2), your primary key on Employee should really be CustomerId, EmployeeId. Two customers could have the same employee ID number. Then Kieron's foreign key will work.
I recently pass to a similar situation, consider the schema:
Table company (id_cia PK) Table product_group (id_cia FK to company, id_group PK) Table products (id_group FK to product_group, id_product PK, id_used_by_the_client null)
Rule: The database must allow only one id_used_by_the_client for each product of a company but this filed can be null. Example:
Insert into company (1) = allowed
Insert into company (2) = allowed
Insert into product_group (1, 1) = allowed
Insert into product_group (1,2) = allowed
Insert into product_group (2,3) = allowed
Insert into products values (1, 1, null) = allowed
Insert into products values (1, 2, null) = allowed
Insert into products values (1, 3, 1) = allowed
Insert into products values (1, 4, 1) = not allowed, in the group 1 that belongs to company 1 already exists an id_used_by_the_client = 1.
Insert into products values (2, 4, 1) = not allowed, in the group 2 that belongs to company 1 already exists an id_used_by_the_client = 1.
Insert into products values (3, 4, 1) = allowed, in the group 3 that belongs to company 2 there is no id_used_by_the_client = 1.
I decided to use a trigger to control this integrity.
Either:
make the EmployeeID column the Primary Key of Employee (and possibly an auto-id) and store the EmployeeID in the WorkItem record as a foreign key, instead of storing the Employee and Customer IDs in WorkItem. You can retrieve a WorkItem's Customer details by joining to the Customer table via the Employee table.
Or:
make the WorkItem's EmployeeID and CustomerID columns a composite foreign key to Employee.
I favour the first approach, personally.