Insert Multiple Tables into one Table - sql

Http://i.stack.imgur.com/z0fSP.png
Http://i.stack.imgur.com/Nd3nB.png
Http://i.stack.imgur.com/5qtRh.png
Http://i.stack.imgur.com/01PVc.png
Http://i.stack.imgur.com/wvibY.png
INSERT INTO OrderArchive
(OrderNumber,OrderDate,StockItem,Quantity,UnitPrice,SalesRep,Customer,ArchiveDate)
SELECT "ORDER".OrderNo,
"ORDER".OrderDate,
Stock.StockNo||' '||Stock.StockDesc,
Orderline.Quantity,
Orderline.UnitPrice,
Person.FirstName||' '||Person.Surname,
Person.FirstName||' '||Person.Surname,
OrderArchive.ArchiveDate
FROM "ORDER"
INNER JOIN Stock
ON Stock.StockNo||' '||Stock.StockDesc = OrderAchive.StockItem
INNER JOIN Orderline
ON Orderline.Quantity = OrderArchive.Quantity
INNER JOIN Orderline
ON Orderline.UnitPrice = OrderArchive.UnitPrice
INNER JOIN Person
ON Person.FirstName||' '||Person.Surname = OrderArchive.SalesRep
INNER JOIN Person
ON Person.FirstName||' '||Person.Surname = OrderArchive.Customer
WHERE "ORDER".OrderDate < DATEADD('M',6,SYSDATE);
I tried to work it out first, but just couldnt manage it .... i am trying to move orders that are older than 6 months to OrderArchive...OrderArchive has OrderNo & Orderdate that come from "ORDER"Table Stock item which is a combination of StockID and Stockdesc from stock table quantity and unit cost are from orderline table salesrep and customer are from person Table and datearchived is a sysdate of the date the order was archived

To do this, you need a way to join the Person record to the TableOrder record. This code assumes you have a PersonID on the TableOrder table. You might have a CustomerID or SalesPersonID or something like that on your TableOrder table to join it to the Person table, but I'm not clear on that.
INSERT INTO ArchiveTable (col_1,col_2,col_3,col_4 etc)
SELECT
o.OrderNo,
o.OrderDate,
p.StockNo||' '||p.StockDesc,
p.FirstName||' '|| p.Surname
FROM TableOrder o
INNER JOIN Person p
ON p.PersonID = o.PersonID
WHERE o.orderdate < DATEADD('M',12,SYSDATE)

I think that you are not getting the expected output from the query, because you are joining the Person table with both SalesRep and Customer names at the same time. Thus, only if an Order has the same name for both SalesRep and Customer, will you get any data. Therefore, I have created different table aliases for the Person table, as below:
INSERT INTO OrderArchive
(OrderNumber,OrderDate,StockItem,Quantity,UnitPrice,SalesRep,Customer,ArchiveDate)
SELECT
"ORDER".OrderNo,
"ORDER".OrderDate,
Stock.StockNo||' '||Stock.StockDesc,
Orderline.Quantity,
Orderline.UnitPrice,
Person_SR.FirstName||' '||Person_SR.Surname,
Person_C.FirstName||' '||Person_C.Surname,
OrderArchive.ArchiveDate
FROM "ORDER"
INNER JOIN Stock
ON Stock.StockNo||' '||Stock.StockDesc = OrderAchive.StockItem
INNER JOIN Orderline
ON Orderline.Quantity = OrderArchive.Quantity
INNER JOIN Orderline
ON Orderline.UnitPrice = OrderArchive.UnitPrice
INNER JOIN Person Person_SR
ON Person_SR.FirstName||' '||Person_SR.Surname = OrderArchive.SalesRep
INNER JOIN Person Person_C
ON Person_C.FirstName||' '||Person_C.Surname = OrderArchive.Customer
WHERE "ORDER".OrderDate < DATEADD('M',6,SYSDATE);

INSERT INTO OrderArchive (OrderNumber,OrderDate,StockItem,Quantity,UnitPrice,SalesRep,Customer)
SELECT "ORDER".OrderNo,
"ORDER".OrderDate,
Stock.StockNo ||' '|| Stock.StockDesc,
Orderline.Quantity,
Stock.UnitCost,
"ORDER".SalesRepID,
Person.FirstName||' '||Person.Surname
FROM Person INNER JOIN
("ORDER" LEFT JOIN
(Orderline INNER JOIN Stock
ON Orderline.StockID=Stock.StockNo)
ON"ORDER".OrderNo=OrderLine.OrderNo)
ON Person.PersonID="ORDER".CustomerID
WHERE "ORDER".OrderDate < ADD_MONTHS (SYSDATE,-6)
ORDER BY "ORDER".OrderNo;
SELECT * FROM OrderArchive;
Nearly Done i just have to get SalesRepID to say firstname surname of salesrep but mostly done :)

Related

SQL Server stored procedure query multiple tables

I am querying a SQL Server database using a stored procedure.
My database tables include:
Customers
SalesOrders - Linked to the customers with an id
SalesOrderLines - Linked to the SalesOrders with an id
SalesOrderReleases - Linked to the SalesOrderLines with an id, stores the quantity on the order line that has been released and ready to manufacture, the SalesOrderLine quantity can be all on one release or split up on multiple
FinishedGoods - linked to the SalesOrderLines with an id, stores the quantity of the SalesOrderLine where manufacturing is complete, the SalesOrderLine quantity can be all on one FinishedGood entry or split up on multiple
I need to retrieve all the customers that have SalesOrderLines with SalesOrderReleases and FinishedGoods where the total quantity finished is less than the total quantity released
I have tried this SQL code but Customers appear repeatedly in the results
SELECT
Customer.ID, Customer.Name
FROM
Customer
INNER JOIN
SalesOrder ON Customer.ID = SalesOrder.CustomerID
INNER JOIN
SalesOrderLine ON SalesOrder.ID = SalesOrderLine.SalesOrderID
INNER JOIN
SalesOrderRelease ON SalesOrderLine.ID = SalesOrderRelease.SalesOrderLineID
INNER JOIN
FinishedGood ON SalesOrderLine.ID = FinishedGood.SalesOrderLineID AND FinishedGood.Quantity < SalesOrderRelease.Quantity
I am looking for a SQL code snippet that will query multiple tables the way I have described.
try this code:
SELECT Customer.ID, Customer.Name FROM Customer
INNER JOIN SalesOrder ON Customer.ID = Order.CustomerID
INNER JOIN SalesOrderLine ON Order.ID = OrderLine.OrderID
INNER JOIN
(SELECT OrderID, OrderLineID, SUM (Quantity) AS SRQuantity FROM
SalesOrderRelease GROUP BY OrderID, OrderLineID) AS SRQ
ON SRQ.OrderID = SalesOrderLine.OrderID
INNER JOIN
(SELECT OrderLineID, SUM (Quantity) AS FGQuantity FROM
FinishedGoods GROUP BY OrderLineID) AS FGQ
ON SRQ.OrderLineID = FGQ.OrderLineID
WHERE FGQ.FgQuantity < SRQ.SRQuantity
Credits to Sergey for his answer, I was able to use the sample code he provided with several slight modifications:
SELECT Customer.ID, Customer.Name FROM Customer
INNER JOIN SalesOrder ON Customer.ID = SalesOrder.CustomerID
INNER JOIN SalesOrderLine ON SalesOrder.ID = SalesOrderLine.SalesOrderID
INNER JOIN
(SELECT SalesOrderID, SalesOrderLineID, SUM (Quantity) AS SRQuantity FROM
SalesOrderRelease GROUP BY SalesOrderID, SalesOrderLineID) AS SRQ
ON SRQ.SalesOrderLineID = SalesOrderLine.SalesOrderID
LEFT JOIN
(SELECT SalesOrderLineID, SUM (Quantity) AS FGQuantity FROM
FinishedGood GROUP BY SalesOrderLineID) AS FGQ
ON SRQ.SalesOrderLineID = FGQ.SalesOrderLineID
WHERE ISNULL(FGQ.FgQuantity, 0) < SRQ.SRQuantity
The last join needed to be a Left Join
When comparing the FgQuantity and the SRQuantity in the last line, I needed to have it check for NULL values
With these modifications everythings works perfectly!

Joining two indirectly related tables without including columns from tables in between

Based on the following ERD, I'm trying to write a query that displays reservations made directly by customers and include reservation id, reservation date, customer id, customer first name, tour trip id, tour category name, tour trip date
I've been able to include everything in my query except for the tour category name because the TOUR_SITES table is in the way. Is there a way I can join the category name from the TOUR_PACKAGE table without adding any extra columns?
SELECT r.RESERVATION_ID, r.RESERVATION_DATE,
c.CUSTOMER_ID, c.FIRST_NAME,t.TRIP_ID, o.TRIP_DATE/*, P.CATEGORY_NAME*/
FROM CUSTOMER c
INNER JOIN RESERVATION r
ON
r.CUSTOMER_ID=c.CUSTOMER_ID
INNER JOIN TOURTRIP_RESERVATION t
ON
r.RESERVATION_ID=t.RESERVATION_ID
INNER JOIN TOUR_TRIP O
ON
t.TRIP_ID=o.TRIP_ID
WHERE AGENT_ID IS NULL;
Is there a way I can join the category name from the TOUR_PACKAGE table without adding any extra columns?
Sure; just join all tables you need. You don't have to add additional columns (the ones you don't need) into the select column list, but you do have to use the tour_sites table anyway.
Something like this:
select r.reservation_id, r.reservation_date,
c.customer_id, c.first_name,t.trip_id, o.trip_date,
p.category_name
from customer c inner join reservation r on r.customer_id=c.customer_id
inner join tourtrip_reservation t on r.reservation_id=t.reservation_id
inner join tour_trip o on t.trip_id=o.trip_id
--
join tour_sites s on s.tour_siteid = o.tour_siteid --> add
join tour_package p on p.category_id = s.category_id --> this
where agent_id is null;
You need to first join tour_sites with tour_trip on TOUR_SITEID and then join tour_package with tour_sites on category_id to get the tour category_name. You can join left join on tour_sites in case there are no tour sites assigned for a tour trip like a newly added tour_trip.
SELECT r.RESERVATION_ID, r.RESERVATION_DATE, c.CUSTOMER_ID, c.FIRST_NAME,t.TRIP_ID, o.TRIP_DATE,TP.CATEGORY_NAME
FROM CUSTOMER c
INNER JOIN RESERVATION r ON r.CUSTOMER_ID=c.CUSTOMER_ID
INNER JOIN TOURTRIP_RESERVATION t ON r.RESERVATION_ID=t.RESERVATION_ID
INNER JOIN TOUR_TRIP O ON t.TRIP_ID=o.TRIP_ID
LEFT JOIN TOUR_SITES TS ON TS.TOUR_SITEID = O.TOUR_SITEID
INNER JOIN TOUR_PACKAGE TP ON TP.CATEGORY_ID = TS.CATEGORY_ID
WHERE AGENT_ID IS NULL;

SQL - joining multiple tables

I have three tables that I'm trying to join:
sales
order
employee
For example, the tables have the following attributes.
Sales:
ID
price
Order:
ID
tag
Employee:
tag
yearsWorked
I would like to keep only records that exist from the result of a left join in sales and order -> left join the result with employee
SELECT *
FROM ( SELECT *
FROM SALES
LEFT JOIN ORDER
ON SALES.ID = ORDER.ID) AS SO
LEFT JOIN EMPLOYEE
on SO.TAG = EMPLOEYE.TAG;
The above query does not work.
There is no need for a subquery. All you have to do is 2 LEFT JOIN, each for the respective table. This will make sure that only the results of the first left join are joined with the third table.
SELECT *
FROM SALES S
LEFT JOIN ORDER O ON S.ID = O.ID
LEFT JOIN EMPLOYEE E ON O.TAG = E.TAG;
I hope this works.
SELECT
*
FROM
Order
LEFT JOIN Sales
ON Order.ID = Sales.ID
LEFT JOIN Employee
ON Order.tag = Employee.tag

Sql group by and join issue

Perhaps just because I have had insufficient sleep this weekend, but I cannot seem to fix it.
I have these tables:
Products (PK Productid with fk categoryid)
ShippedProducts (PK ShippedProductsID with FK ShipmentID and fk productid)
Shipments (PK ShipmentID with FK InvoiceID)
Invoices (PK InvoiceID with FK CustomerID)
Customers (PK CustomerID with FK CountryId)
Countries (PK CountryID)
sorry, no other way to explain the schema. Please let me know if I can give a better overview for the data structure.
Here is my SQL (database is Microsoft SQL server 2008)
SELECT countries.countryid,
countryname,
isnull(round(sum(InvoiceTotal), 2),0) as TotalInvoice,
count(invoices.invoiceid) as nrOfInvoices,
count(shipments.shipmentid) as nrOfShipments
FROM INVOICES
inner join customers on invoices.CustomerID = customers.customerid
inner join countries on customers.CountryID = COUNTRIES.CountryID
inner join shipments on shipments.invoiceid = invoices.invoiceid
inner join ShippedProducts on ShippedProducts.ShipmentID = shipments.ShipmentID
group by countryname, COUNTRIES.CountryID, CurrencyName, CURRENCIES.CurrencyID
If I comment out the last inner join (with shippedproducts) I get the right number of invoices etc. but when I inner join the shippedproducts the count does not count the invoiceid but somehow the number of productrows from the shipment.
If I add more things to the group by, It does not group anymore by the country and I have a row for each invoice and shipment etc.
I somehow do not manage to see my mistake this monday. Perhaps I just need more coffee.
You should be able to use a windowing function to do this without a group by. Like this
SELECT
countries.countryid,
countryname,
isnull(round(sum(InvoiceTotal) over (partition by invoice.invoiceID), 2),0)
as TotalInvoice,
count(invoices.invoiceid)
over (partition by countries.countryid) as nrOfInvoicesPerCountry,
count(shipments.shipmentid) over (partition by coutries.countryid)
as nrOfShipments
FROM INVOICES
inner join customers on invoices.CustomerID = customers.customerid
inner join countries on customers.CountryID = COUNTRIES.CountryID
inner join shipments on shipments.invoiceid = invoices.invoiceid
inner join ShippedProducts on ShippedProducts.ShipmentID = shipments.ShipmentID
It appears your problem is joining on a 1 to many relationship.
I think you should either put your count of ShippedProducts.ShipmentProductsID into a subselect in your select statement. Something like this perhaps..
select countries.countryid,
countryname,
isnull(round(sum(InvoiceTotal), 2),0) as totalInvoice,
count(invoices.invoiceid) as nrOfInvoices,
count(shipments.shipmentid) as nrOfShipments
(select count shipmentproductsid from shipmentproducts where shipmentproducts.shipmentid = shipments.shipmentID) as totalProd
from invoices
inner join customers on invoices.customerid = customers.customerid
inner join countries on customers.countryid = countries.countryid
inner join shipments on shipments.invoiceid = invoices.invoiceid
group by countryname, countries.countryid , currencyname, currencies.currencyid

Combining multiple SQL Queries

I want to make a query to list cats that took longer than average cats to sell?
I have five tables:
Animal, Sale, AnimalOrderItem, AnimalOrder, and SaleAnimal
Animal table: AnimalID, Name, Category
(cat, dog, fish)
SaleAnimal table: SaleID, AnimalID,
SalePrice
Sale table: SaleID, date, employeeID,
CustomerID
AnimalOrderItem table: OrderID,
AnimalID, cost
AnimalOrder: OrderID, OrderDate,
ReceivingDate,
SupplierID, ShippingCost, EmployeeID
There is other tables I don’t think they have an effect on the query.
I thought of the following ... make a query to calculate days to sell for all ex.:
[SaleDate]-[ReceiveDate] AS DaysToSell
Have the INNER JOIN built:
Sale INNER JOIN ((AnimalOrder INNER JOIN (Animal INNER JOIN AnimalOrderItem
ON Animal.AnimalID = AnimalOrderItem.AnimalID) ON AnimalOrder.
OrderID = AnimalOrderItem.OrderID) INNER JOIN SaleAnimal ON Animal.
AnimalID = SaleAnimal.AnimalID) ON Sale.SaleID = SaleAnimal.SaleID
Create another query based on the above query
SELECT AnimalID, Name, Category, DaysToSell
WHERE Category="Cat" AND DaysToSell>
(SELECT Avg(DaysToSell)
FROM the earlier query
WHERE Category="Cat"
ORDER BY DaysToSell DESC;
After running the query it I got error saying
ORA-00921: unexpected end of SQL
command
Any suggestions! please
Queries can be combined with a subquery. For example,
select *
from (
select *
from mytable
) subquery
Applying this pattern to your problem seems fairly straightforward.
I don't see the closed bracket that matches with the select avg
Ok, I've come up with this:
SELECT AnimalID, Name, Category,
[SaleDate]-[ReceiveDate] AS DaysToSell
FROM Sale INNER JOIN ((AnimalOrder INNER JOIN (Animal INNER JOIN AnimalOrderItem ON Animal.AnimalID = AnimalOrderItem.AnimalID) ON AnimalOrder.OrderID = AnimalOrderItem.OrderID)
INNER JOIN SaleAnimal ON Animal.AnimalID = SaleAnimal.AnimalID) ON Sale.SaleID = SaleAnimal.SaleID
WHERE Category = "Cat"
AND ([SaleDate]-[ReceiveDate]) > (SELECT AVG([SaleDate]-[ReceiveDate])
FROM Sale INNER JOIN ((AnimalOrder INNER JOIN (Animal INNER JOIN AnimalOrderItem ON Animal.AnimalID = AnimalOrderItem.AnimalID) ON AnimalOrder.OrderID = AnimalOrderItem.OrderID)
INNER JOIN SaleAnimal ON Animal.AnimalID =SaleAnimal.AnimalID) ON Sale.SaleID = SaleAnimal.SaleID
WHERE Category = "Cat")
ORDER BY ([SaleDate]-[ReceiveDate]) DESC;