I need to add a constraint when creating a table, Order, such that the unique combination of fields exist within another table.
Table: Product
productId PRIMARY KEY
productNumber
and,
Table: Order
clientId FOREIGN KEY
productId FOREIGN KEY
productNumber
dateBorrowed
dateReturned
I have two tables Product and Order. The productId and productNumber create a unique combination to specify a product as multiple versions of the same product may exist.
When entering values into the Order table the unique combination of productId and productNumber must exist within the Product table, duplicates are allowed as items can be returned and borrowed again at a later date.
I'm not sure how I would go about coding the constraint when creating the Order table, hope that all made sense.
Example Data:
Product
ProductId
ProductNumber
123
1
123
2
675
1
Table
clientId
productId
productNumber
dateBorrowed
dateReturned
10
123
1
1979
1989
10
123
1
1990
2000
12
675
1
2022
2022
07
123
2
1982
2022
The unique combination of fields you describe is in fact the primary key :
CREATE TABLE Product(
productId INTEGER,
productNumber INTEGER,
...
PRIMARY KEY (productId, productNumber)
);
You can reference it in the Order table :
CREATE TABLE "Order"(
...
productId INTEGER,
productNumber INTEGER,
...
FOREIGN KEY(productId, productNumber) REFERENCES Product(productId, productNumber)
);
Please note the Order table name must be quoted, ORDER is a SQLite keyword.
Also foreign keys must be enabled :
PRAGMA foreign_keys = ON;
Related
I am trying to create a many-to-many relationship between two tables Asset and Inventory, I created an intermediate table called Asset_Inventory
One or more assets can be in an inventory, and an inventory can be in one or more assets,but it does not allow me to insert data
Mistake
The data in row 2 was not committed. Error source Message: Violation of PRIMARY KEY CONSTRAINT
PK_INVENTORY_ASSET. Cannot insert duplicate key in object dbo.Inventory_Asset. The duplicate key value (1,1).
-- TABLE INVENTORY
GO
CREATE TABLE Inventory
(
[inventory_id] INT NOT NULL IDENTITY(1,1),
[company_id] INT,
[name] VARCHAR(50),
[observations] VARCHAR(500),
[date_created] DATETIME DEFAULT(GETDATE()),
CONSTRAINT PK_INVENTORY PRIMARY KEY (inventory_id),
CONSTRAINT FK_INVENTORY_COMPANY FOREIGN KEY(company_id) REFERENCES Company(company_id)
)
-- TABLE ASSET
GO
CREATE TABLE Asset
(
[asset_id] INT NOT NULL IDENTITY(1,1),
[company_id] INT,
[code] INT,
[model_name] VARCHAR(50),
[model_number] VARCHAR(50),
[serial_number] VARCHAR(30),
[price] DECIMAL(10,2),
CONSTRAINT PK_ASSET_ID PRIMARY KEY(asset_id),
CONSTRAINT FK_ASSET_COMPANY FOREIGN KEY(company_id) REFERENCES Company(company_id),
CONSTRAINT UQ_ASSET_CODE UNIQUE(code)
)
--TABLE INVENTORY_ASSET
CREATE TABLE Inventory_Asset
(
asset_id INT,
inventory_id INT,
CONSTRAINT PK_INVENTORY_ASSET PRIMARY KEY (asset_id,inventory_id),
CONSTRAINT FK_ASSET_ID FOREIGN KEY (asset_id) REFERENCES Asset(asset_id),
CONSTRAINT FK_IVENTORY_ID FOREIGN KEY (inventory_id) REFERENCES Inventory(inventory_id)
)
UPDATED
it's hard for me to ask this question
N companies have many assets; you need to have control over them. Have a list of assets by company, to which employee it was assigned, or in which department of the company that asset is located. a total of assets by company etc..
What is the purpose of this?
I need to physically label (bar code) each asset with a unique code
Cell phones, monitors, keyboards, servers, PCs, laptops, chairs, furniture, etc...
Once all the assets have been tagged in the
company 1
company 2
company 3
I have to scan each code printed on the asset and make a monthly cut
I have to create a report with this information
In the company 1 an inventory was made in the month of January
Cut of the month of January:
20 monitors (10 dell , 10hp)
20 chairs
10 computers
the next month this cut is made again to see if there is the same quantity, if the 2 inventories of the month of January and February are not the same, some asset was stolen and to be able to identify this
an inventory can have one or more assets, and an asset can be in one or more inventories.
I think I can do this with the Inventory_Asset table
asset_id
iventory_id
1
1
1
1
2
1
3
1
1
1
1
2
2
2
1
2
6
2
1
3
4
3
3
3
1
3
Am I wrong with my solution?
--TABLE INVENTORY_ASSET
CREATE TABLE Inventory_Asset
(
[inventory_id] INT,
[asset_id] INT,
CONSTRAINT FK_ASSET_ID FOREIGN KEY (asset_id) REFERENCES Asset(asset_id),
CONSTRAINT FK_IVENTORY_ID FOREIGN KEY (inventory_id) REFERENCES Inventory(inventory_id)
)
CONSTRAINT PK_INVENTORY_ASSET PRIMARY KEY (asset_id,inventory_id),
PRIMARY KEYS must be unique. That is why you can't add this -- since it conflicts with your primary key. If you don't want that to be unique but you do expect to use it as an index you can make an index that does not enforce uniqueness and make something else your primary key.
The answers and comments here are all correct; but perhaps we need to review what a many-to-many relation can be used for.
Option 1: we just need a link between two entities
This is what you have done. Basically it will serve if you want to know in which Inventories a given Asset is, which Assets a given Inventory holds, etc. In this scenario when you have established the link once (Asset 1 is in Inventory 1) there's no reason to re-establish it with further records.
Option 2: we want to store some information about the relation
This is what I suspect you really wanted. Suppose for instance you want to store how many Assets of type 1 are in Inventory 1. In this case what you want is to add a "Quantity" column to your Inventory_asset table. Once more, if there are 3 Assets of type 1 in Inventory 1 you won't duplicate the records: you will just create one record and put 3 in the new column.
Option 3: we really need multiple records
Suppose you want to store not only how many Assets of a given type are in a given Inventory, but also on which date a few of them were put there. So you may have 2 type 1 Assets put in Inventory 1 on May, 1st, and other 3 of them on May, 15th. In this case the date must become part of the PK, so that the system (and you too!) can distinguish between the different records. You may also decide to create an auto-increment column and use it as a PK instead; but note that while it may be simpler to handle, it would allow for unvoluntarily creating duplicate records, so I wouldn't recommend it.
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 have a table that I need to insert data into.
The table Sales has 4 columns
CustomerValueType_id (int)
Customer_id (int)
Value (NVARCHAR)
Customer_name (NVARCHAR)
The CustomerValueType_id, Customer_id are foreign keys that are not-unique, CustomerValueType_id matches to a value type, while Customer_id matches to the Customer_name.
I need to add additional customer data into the Valuecolumn but how do I ensure that the data matches to the correct CustomerValueType_id and Customer_id and each customer name has to be repeated in the Customer_name
Sales Table
You are trying to do denormalization.
Ideally, in the normalized design, you will just store, parent_ids in
the child table. If you want to see parent_name fields, you have to
get them based on JOIN conditions.
But, here as you are storing both id, name in the child table, I would suggest you to create composite Foreign key in the child table, so that the combination is always present. Also, make this combination as composite primary key in the parent table.
-- Parent Table PRIMARY KEY
ALTER TABLE dbo.CustomerValueType
ADD CONSTRAINT PK_CustomerValueType
PRIMARY KEY CLUSTERED (CustomerValueType_id, Value);
GO
--Child Table FOREIGN KEY
ALTER TABLE dbo.Sales
ADD CONSTRAINT FK_Sales_CustomerValueType
FOREIGN KEY (CustomerValueType_id,Value)
REFERENCES dbo.CustomerValueType(CustomerValueType_id,Value);
GO
Watch out, learning sql newbie. I would like to create 2 simple tables.
products: id | product_name
order_table: id | buyer_name | purchased_products
CREATE TABLE products (
id INTEGER PRIMARY KEY,
product_name TEXT
);
CREATE TABLE order_table (
id INTEGER PRIMARY KEY,
buyer_name TEXT,
purchased_products NUMERIC ARRAY
);
Currently the link is numeric, but this would require the report generation to know that purchased_products is referring to the products table. Is it possible to define that the purchased_products must be referring to the products?
Note: this is sqlite3,
Remove the field purchased_products and create one more table, like this:
order_product: id | order_id | product_id
Now, you should declare that order_id is a foreign key referring to the field id of the table order_table, and that product_id does the same for products.
There are some categories and its products. But products is used for another categories. For example, There are "metal handles" categories and it is used for "metal handles" but at the same time it is used for "children handles". I should say them that you belong to "metal handles" but you could be in "children handles" too
How do I create these tables?
Thanks
Frankly do not understand that you really need. Here is three possible cases:
Product and Categories - many to many relations
You need three tables for resolve many to many relations
Categories(Id, CategoryName)
Products(Id, ProductName)
CategoryProducts(ProductId, CategoryId)
Hierarchical structure for Categories
Categories(Id, CategoryName, ParentCategoryId)
Products(Id, ProductName, CategoryId)
Map structure for Categories
Categories(Id, CategoryName)
CategoryMap(CategoryId, PartOfCategoryId)
Products(Id, ProductName, CategoryId)
I believe what you're talking about is an arc relationship. You'd use something like:
Categories Products ProductCategories
----------- --------- -----------------
Id Id Id
Description Description ProductId
CategoryId
This way, your "Metal Handles" Category could have an Id of (say) 247, and your "Metal Handles" product could be Id 49 while "Children Handles" is 1022, and the rows in ProductCategories would look like this:
Id ProductId CategoryId
1 49 247
2 1022 247
The following is a pretty conventional setup.
One row will be present in this table for every category:
CREATE TABLE Category
(
CategoryId int not null identity(1,1)
constraint PK_Category
primary key clustered
,Name varchar(50) not null
,(etc.)
)
Sample data:
1 Metal Handles
2 Wooden Handles
3 Plastic Handles
One row will be present in this table for every product:
CREATE TABLE Product
(
ProductId int not null identity(1,1)
constraint PK_Product
primary key clustered
,Name varchar(50) not null
,(etc.)
)
Sample Data:
101 Pots
102 Pans
103 18th Century Composers
And one row will be present in here for every relationship between a product and a category
CREATE TABLE ProductCategory -- Seems more suitable than "CategoryProduct"
(
ProductId int not null
constraint FK_ProductCategory__Product
foreign key references Product (ProductId)
,CategoryId int not null
constraint FK_ProductCategory__Category
foreign key references Category (CategoryId)
,constraint PK_ProductCategory
primary key clustered (ProductId, CategoryId)
)
Sample data:
101 1
101 2
101 3
102 1
102 2
103 2
Here, product "Pots" is associated with all three handles, while "Pans" is associated only with two. On the flip side, category "Metal" is associated with two products, while "Wood" is associated with three.