SQL creating a join between two tables - sql-server

I want to create three tables.
Orders (contains an order ID and a customer name)
Products (contains a Product ID, description, and price)
Line Item (contains Order ID, Line Item ID, Product ID, and Quantity)
I want my web app to allow a customer to select an order number, and as a result, it will display the products that are in that order, the quantity of said products, the price of the products, and a total price of order that will be calculated on the fly in my code behind.
My SQL looks like this
CREATE TABLE Products
(
ProductID int NOT NULL,
ProductDescription varchar(MAX) NOT NULL,
ProductPrice smallmoney NOT NULL,
PRIMARY KEY (ProductID)
)
CREATE TABLE Orders(
OrderID int NOT NULL,
CustomerName varchar(MAX) NOT NULL,
PRIMARY KEY (OrderID)
)
CREATE TABLE LineItem(
LineItemID int NOT NULL,
OrderID int NOT NULL FOREIGN KEY REFERENCES Orders(OrderID),
ProductID int NOT NULL FOREIGN KEY REFERENCES Products(ProductID),
Quantity int NOT NULL,
PRIMARY KEY (LineItemID)
)
Here is the database diagram with the relationships.
Here is the result of a select all statement on all the tables
Are my relationships set up correctly for what I want to achieve? I'm sorry if this seems simple but I'm new to this and while the SQL Statements are pretty easy, the way to relate tables is not.

SELECT p.ProductPrice, p.ProductDescription, o.CustomerName, l.Quantity
FROM LineItem AS l
INNER JOIN Products AS p ON l.ProductID=p.ProductID
INNER JOIN Orders AS o ON l.OrderID=o.OrderID
ORDER BY l.LineItemID
will provide combined information from all of these tables. You may add any additional columns which you want to fetch data from.
INNER JOIN and JOIN keywords are syntactic sugar, which have same effect. While you're binding two tables by INNER JOIN, only results which contained in both of these tables will be returned.
With the ON keyword, you are defining the relational columns of tables. For example, in the clause INNER JOIN Products AS p ON l.ProductID=p.ProductID, I'm defining that the data are relational in column ProductID of table Products with column ProductID of table LineItem.

You have a many-to-many relationship between Products and Orders so in the structure of LineItem table I think you already have have the primary key (Product Id,OrderID) and I think you do not need to LocalItemID
CREATE TABLE LineItem(
OrderID int NOT NULL FOREIGN KEY REFERENCES Orders(OrderID),
ProductID int NOT NULL FOREIGN KEY REFERENCES Products(ProductID),
Quantity int NOT NULL,
PRIMARY KEY (OrderID ,ProductID )
)
and you can join the tables using this:
SELECT p.ProductPrice, o.CustomerName, li.Quantity
FROM LineItem AS li
JOIN Products AS p ON li.ProductID=p.ProductID
JOIN Orders ON li.OrderID=o.OrderID

Related

How do i update a column with specific values to reference the primary key ID of another table?

My goal is to normalize my table. My table before normalization is called Product Specifications, to normalize it I have two other tables called buyers_table and product_table
Table "Product Specifications"
Columns: Product_id , model_number, buyer
Buyers_table
Column: Buyer_id, buyer
Product_table
product_id, model_number, buyer_id
How do I insert the buyers from my product_specification table into my product_table but have the values show up as the buyer_id value instead of buyer?
Sorry I am new to this. This is a simplified version of the database that I have set up for my company.
use this design for database
Product_buyer: Columns:Id, Product_id , Buyer_id
Buyers_table: Column: Id, Buyername
Product_table: Id, Model_number
Product_Specifications: Id,Product_id,Productname,Price
then For insert data to database
First enter the information in the Product_table table
Retrieve the latest Product_table table record and enter Id as Product_id and the other of the information in the Product_Specifications table.
Enter the buyer information in the Buyers_table table when purchasing
Product_buyer
Create tables
create table Product_table
(
Id int identity,
Model_number int,
primary key(Id));
create table Product_Specifications
(Id int identity,
Product_id int,
Productname nvarchar(150),
Price int,
primary key(ID),
foreign key(Product_id) references Product_table);
//**********************
//and define other table
//......................
Retrieve product information
select Product_table.Id,Product_table.Model_number,Product_Specifications.Productname,Productname.Price
from Product_table join Product_Specifications
on Product_table.Id = Product_Specifications.Product_id
Retrieve Product_buyer information
select Product_table.Id,Product_table.Model_number,Product_Specifications.Productname,Productname.Price,Buyers_table.Id,Buyers_table.Buyername
from Buyers_table join Product_buyer on Buyers_table.Id = Product_buyer.Buyer_id
join Product_table on Product_buyer.Product_id = Product_table.Id
join Product_Specifications on Product_table.Id = Product_Specifications.Product_id

How do I avoid duplicates on an SQL primary key?

Complete beginner here. I'm trying to create this simple joint table on SSMS but I'm getting this duplicate error regarding the primary key:
Msg 2627, Level 14, State 1, Line 23
Violation of PRIMARY KEY constraint 'PK__FactOffl__B14003C24ECE0589'. Cannot insert duplicate key in object 'dbo.FactOfflineSales'. The duplicate key value is (43659).
What am I doing wrong?
CREATE TABLE FactOfflineSales
(
SalesOrderID int NOT NULL PRIMARY KEY,
SalesOrderNumber nvarchar(20) NOT NULL,
SalesPersonID int NULL,
CustomerID int NULL,
SpecialOfferID int NOT NULL,
TerritoryID int NOT NULL,
ProductID int NOT NULL,
CurrencyRateID int NULL,
OrderQuantity smallint NULL,
UnitPrice money NULL,
SubTotal money NULL,
TaxAmount money NULL,
Freight money NULL,
LineTotal money NULL,
UnitPriceDiscount float NULL,
OrderDate datetime NULL,
ShipDate datetime NULL,
DueDate datetime NULL,
OnlineOrderFlag int NULL
);
INSERT INTO FactOfflineSales (
SalesOrderID
,SalesOrderNumber
,SalesPersonID
,CustomerID
,SpecialOfferID
,TerritoryID
,ProductID
,CurrencyRateID
,OrderQuantity
,UnitPrice
,SubTotal
,TaxAmount
,Freight
,LineTotal
,UnitPriceDiscount
,OrderDate
,ShipDate
,DueDate
,OnlineOrderFlag
)
SELECT
SalesOrderHeader.SalesOrderID
,SalesOrderHeader.SalesOrderNumber
,SalesOrderHeader.SalesPersonID
,SalesOrderHeader.CustomerID
,SalesOrderDetail.SpecialOfferID
,SalesOrderHeader.TerritoryID
,SalesOrderDetail.ProductID
,SalesOrderHeader.CurrencyRateID
,SalesOrderDetail.OrderQty
,SalesOrderDetail.UnitPrice
,SalesOrderHeader.SubTotal
,SalesOrderHeader.TaxAmt
,SalesOrderHeader.Freight
,SalesOrderDetail.LineTotal
,SalesOrderDetail.UnitPriceDiscount
,SalesOrderHeader.OrderDate
,SalesOrderHeader.ShipDate
,SalesOrderHeader.DueDate
,SalesOrderHeader.OnlineOrderFlag
FROM
AdventureWorks2019.Sales.SalesOrderHeader SalesOrderHeader
LEFT JOIN
AdventureWorks2019.Sales.SalesOrderDetail SalesOrderDetail ON SalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID;
You can not insert the duplicate value in primary key column.
You table FactOfflineSales has primary key on column SalesOrderID which will hold not null and unique values. But looking at your query it seems like there is one-to-many relationship between salesorderheader and salesorderdetails table. so your select query is giving multiple records for single salesorderid, means multiple records with same salesorderid.
It is not allowed to insert duplicate values in FactOfflineSales.salesorderid. Hence, it is throwing an error.
Best practice is to use auto generated sequence for primary key column. You should add one more column in table and declare it as primary key.(something like FactOfflineSales_id)
Your LEFT JOIN on SalesOrderDetail is mutiplying out rows from SalesOrderHeader, from which the primary key comes.
You need to add SalesOrderDetailID to the table, with that (or that and SalesOrderID together) as the primary key
There is a lot going on here. Let me unpack.
A join between tables helps when there is many to many. What does this mean? It means a header has many detail records and a detail record can belong to many headers. If this is not your case, you don't need a join table.
If you really need a join table, you normally do one of two things. The first would be create a composite key on the IDs from both tables. This would only be unique more than once if you load the table with a query that has dupes (solved with DISTINCT). The second (other option) is create a derived key for the primary key (like IDENTITY) and then have the two fields.
As you are learning, neither apply, but you can play with the queries to learn.
See if adding a distinct in the SELECT eliminates dupes. I don't think this will work, but DISTINCT is good to learn.
When the above fails, add a derived key on the table and then rerun your query. You do this by creating this join table with an Id field that is IDENTITY(1,1) for the PRIMARY KEY
As already mentioned by others, your issue is you have dupes on the primary key, which is sales order Id. Why dupes? Because each header has multiple detail records. On record 2, it will fail, as you had the header's id as your primary key.

Oracle primary key affecting indexes

I had an index working really nicely last night, low I/O all that good stuff. Now this morning I added a primary key to the table and the performance has dropped and the optimizer ignores the index even with hints.. Any advice? Thankyou
Schema structure..
Product
ID PK
Name
Price
Order_Line
Order_ID FK
Product_ID FK
Qty
Orders
ID PK
O_Date date
CustID
Query...
SELECT SUM(OL.QTY) FROM PRODUCT P,ORDERS O, ORDER_LINE OL
WHERE
P.NAME = 'APRICOT JAM'
AND
P.ID = OL.PRODUCT_ID
AND
O.O_DATE = '03-MAR-2014'
AND
OL.ORDER_ID= O.ID
;
The index which it isn't using is a composite index on product which is (name,ID), instead its using products primary key to do an index range scan Thanks!
Product Table
ID PK
Name INDEX01
Price
I would structure your table this way.
Your query is going to range scan because it is going to scan the table for the P.NAME = 'APRICOT JAM' clause in your query.

Update Foreign Key when copying records to a different table

I have two tables which I want to merge together. They both have the same columns. However, the records I want to copy over are referenced by another table.
As a result, when I update the reference to the new table, the references are no longer correct. How should I go about updating the references so that they remain correct?
EDIT - Apologies - a little more detail:
At the moment I have this:
INSERT INTO Suppliers
(Name, Reference, Telephone, Email, ContactName, AddressId, CommentSetId)
SELECT Name, Reference, Telephone, Email, ContactName, AddressId, CommentSetId
FROM Hotels
I want to delete the table "Hotels" but need to make sure the reference from another table "HotelContract" is still correct after copying the records to the table "Suppliers"
EDIT 2 - This is SQL server 2005.
I have a table "HotelContract" which has the Foreign Key "HotelId". I have updated this to "SupplierId", to be used when the hotels have been copied to the "Supplier" table.
If you have another unique key in Hotels and Suppliers (e.g. Name) you can use this key to update SupplierId in HotelContract (drop foreign key constraint to Hotels first). You can do this with a join between HotelContracts, Hotels and Suppliers:
update HotelContract
set SupplierId = S.SupplierId
from HotelContract C
inner join
Hotels H
on H.HotelId = C.SupplierId -- assuming the pk column in Hotels is HotelId
inner join
Suppliers S
on S.Name = H.Name -- assuming Name is unique in both tables
If you don't have such a unique key you have to store the original HotelId (now SupplierId) from Hotels within a temporary column in Supplier. The update of HotelContract is simple in this case.
Restore foreign key of HotelContract afterwards.

integrity constraint in Oracle

Suppose that a table named SuplProd has the columns supplier and product and two entries: (Sony Ericcson, Xperia) and (Apple, iPhone).
I would like to create a table named Orders with columns supplier, product and quantity.
However, I'd like the combination (supplier, product) of table Orders to be limited to contain only entries from SuplProd.
For example, the entry (Sony Ericcson, Xperia, 1) would be valid for the table Orders whereas (Apple, Xperia, 1) would not.
How is this possible in Oracle?
You should create a foreign key in orders table:
create table SuplProd (
supplier ...,
product ...,
constraint SuplProd_pk
primary key( supplier, product)
)
create table Orders
...
supplier ...,
product ...,
qty,
constraint SuplProd_pk
primary key( ... ),
constraint orders_to_suplprod_fk
foreign key ( supplier, product)
references SuplPRod (supplier, product)
)

Resources