SQL Query - stuck on the following scenario: - sql

Does anyone have an idea of how to deal this:
My scenario is I have a CustomerTable, OrderTable, ItemsTable and DeliveryTable
a Customer can make many orders
an order can contain many items
however this is where the problem is, if i have lets say 1 item, with the quantity of 20.. i receive 15 of these into stock and want to send 15/20 to the customer. currently i can assign the DeliveryID to the individual item but that contains all 20.
So my question is do i need a middle table or is there an obvious approach i am missing here?

A Customer can have multiple Orders
An order can have multiple orderlines (items)
An orderline can have multiple deliverylines
A delivery can have multiple deliverylines(maybe even of different
orders)
You can then lookup if a orderline is completed by fetching all deliverylines.
Select
( select name from items where id = ol.itemid ) as itemname,
ol.quantity as quantity_ordered,
( select sum(quantity) from deliverylines dl where dl.olid = ol.id ) as quantity_delivered
from orderlines ol
where orderid = <id>;

Related

What's the use of this WHERE clause

this is an answer to the question : We need a list of customer IDs with the total amount they have ordered. Write a SQL statement to return customer ID (cust_id in the Orders table) and total_ordered using a subquery to return the total of orders for each customer. Sort the results by amount spent from greatest to the least. Hint: you’ve used the SUM() to calculate order totals previously.
SELECT prod_name,
(SELECT Sum(quantity)
FROM OrderItems
WHERE Products.prod_id=OrderItems.prod_id) AS quant_sold
FROM Products
;
So there is this simple code up here, and I know that this WHERE clause is comparing two columns in two different tables. But since We are calculating the SUM of that quantity, why do need that WHERE clause exactly. I really couldn't get it. Why the product_id exactly and not any other column ( p.s: the only shared column between those two tables is prod_id column ) I am still a beginner. Thank you!
First you would want to know the sum for each product - so need to adjust the subquery similar to this:
(SELECT prod_id, Sum(quantity) qty
FROM OrderItems
group by prod_id
) AS quant_sold
then once you know how much for each product, then you can link that
SELECT prod_name,
(SELECT prod_id, Sum(quantity) qty
FROM OrderItems
group by prod_id
) AS quant_sold
FROM Products p
WHERE p.prod_id = quant_sold.prod_id
Run it without the where clause and compare the results. You'll learn a lot that way. specifically focus on two different product Ids ensuring they both have order items and quantities.
You have two different tables involved. There are multiple products. You don't want the sum of all orders on each product; which is what you would get without the where clause. So the where clause correlates the two tables ensuring you only SUM the quantity of each order item for each product between the tables. Personally, I'd use a join, sum, and a group by as I find it easier to read and I'm not a fan of sub selects in the select of another query; but that's me.
SELECT prod_name,
(SELECT Sum(quantity)
FROM OrderItems
WHERE Products.prod_id=OrderItems.prod_id) AS quant_sold
FROM Products
Should be the same as:
SELECT prod_name, Sum(coalesce(P.quantity,0))
FROM Products P
LEFT JOIN orderItems OI
on P.prod_id=OI.prod_id
GROUP BY Prod_Name
'Notes
the above is untested.
a left join is needed because all products should be listed and if a product doesn't have an order, the quantity would be zero.
if we use an inner join, the product would be excluded.
We use coalesce because you'd have a "Null" quantity instead of zero for such lines without an order item.
as to which is "right" well it depends and varies on different cases. each has it's own merits and in different cases, one will perform better than another, and in a different case, vice-versa. See --> Join vs. sub-query
As an example:
Say you have Products A & B
"A" has Order Item Quantities of 1 & 2
"B" has order item Quantities of 10 & 20
If we don't have the where clause every result record would have qty 33
If we have the where product "A" would have 3
product "B" would have qty 30.

How can I find all monitor purchases (not with monitor ID value, instead should use the term 'Monitor')

I have two tables,
I need to find all monitor purchases (but not with monitor ID, instead I should use 'Monitor'). I have made code, but it takes the quantity for all products, not only for 'Monitor'.
The code I made:
select name, Price,sum(quantity)
from Products, Orders
where name='Monitor'
How can I fix this problem?
You need to link the rows of both tables. Right now you are creating the cartesian product, containing every row from the first table combined with every row from the second table. With your screenshot, that's going to be 9 rows in total.
SELECT name, Price, SUM(quantity)
FROM Products, Orders
WHERE name='Monitor'
AND Products.ProductId = Orders.ProductId
Or use JOIN directly to separate the filter condition from the join condition:
SELECT name, Price, SUM(quantity)
FROM Products
INNER JOIN Orders
ON Products.ProductId = Orders.ProductId
WHERE Products.name='Monitor'

Find item name along with the seller id and buyer id such that the seller has sold the item to the buyer

Hi IM trying to build a query for the following sentence for sql.
For each seller and each item sold by the seller, find the total amount sold.
I have 3 tables but not sure If i have to use them all. I have a feeling I need to use at least three tables to get this query but I keep getting an error. Also, I keep getting an error when I try to the following:
select selleruserid, itemid, sum(price) total
from sales_fact s
join items_dim i on i.itemid = s.itemid
join sellers_dim d on d.userid = s.selleruserid
group by selleruserid, itemid
I added a picture below of my tables.
All the information you want is in the fact table, so the other tables do not seem necessary:
select sf.selleruserid, sf.itemid, sum(sf.price) as total
from sales_fact s
group by sf.selleruserid, sf.itemid;
You would need to join in the other tables if you needed other information from the dimension, such as the name.

GROUP BY clause with logical functions

I'm using Oracle 11g Application Express, and executing these commands within the SQL Plus CLI. This is for a class, and I cannot get past this problem. I don't know how to add the total quantity of the items on the orders - I get confused as I don't know how to take the SUM of the QUANTITY per ORDER (customers have multiple orders).
For each customer having an order, list the customer number, the number of orders
that customer has, the total quantity of items on those orders, and the total price for
the items. Order the output by customer number. (Hint: You must use a GROUP BY
clause in this query).
Tables (we will use):
CUSTOMER: contains customer_num
ORDERS: contains order_num, customer_num
ITEMS: contains order_num, quantity, total_price
My logic: I need to be able to calculate the sum of the quantity per order number per customer. I have sat here for over an hour and cannot figure it out.
So far this is what I can formulate..
SELECT customer_num, count(customer_num)
FROM orders
GROUP BY customer_num;
I don't understand how to GROUP BY very well (yes, I have googled and researched it for a bit, and it just isn't clicking), and I have no clue how to take the SUM of the QUANTITY per ORDER per CUSTOMER.
Not looking for someone to do my work for me, just some guidance - thanks!
select o.customer_num,
count(distinct o.order_num) as num_orders,
sum(i.quantity) as total_qty,
sum(i.total_price) as total_price
from orders o
join items i
on o.order_num = i.order_num
group by o.customer_num
order by o.customer_num
First thing:
you have to join the two tables necessary to solve the problem (orders and items). The related field appears to be order_num
Second thing:
Your group by clause is fine, you want one row per customer. But because of the join to the items table, you will have to count DISTINCT orders (because there may be a one to many relationship between orders and items). Otherwise an order with 2 different associated items would be counted twice.
Next, sum the quantity and total price, you can do this now because you've joined to the needed table.
This is also solved by using WHERE:
SELECT orders.customer_num, /*customer number*/
COUNT(DISTINCT orders.order_num) AS "num_orders", /*number of orders/c*/
SUM(items.quantity) as "total_qty", /*total quantity/c*/
SUM(items.total_price) as "total_price" /*total price/items*/
/* For each customer having an order, list the customer number,
the number of orders that customer has, the total quantity of items
on those orders, and the total price for the items.
Order the output by customer number.
(Hint: You must use a GROUP BY clause in this query). */
FROM orders, items
WHERE orders.order_num = items.order_num
GROUP BY orders.customer_num
ORDER BY orders.customer_num
;

sql select orders with similar items

I need to select those orders in pairs who have the same products in them. ORDER_ITEMS contain the product and a foreign key to reference the parent ORDER row. Order rows need to be different.
I've managed to list out pairs with count how many matching products they have in them, but that's only a similarity count. I need to exclude orders from pairs who have different products in them.
Can have Oracle specific stuff in it.
The two tables are:
Order(order_id, customer_id...)
Order_Item(item_id, order_id FK, product_id,...)
I need tose order_id-s that have all Order_Item childs with matching product_id-s.
Ex. in Orders
{ (ord1, cust1)
(ord2, cust2)}
and in Order_Items
{ (item1, ord1, product_id=3),
(item2, ord1, product_id=6),
(item3, ord2, product_id=3),
(item4, ord2, product_id=6) }
So basically, two people bought exactly the same two things. They are a pair. Those orders whose ordered products don't match exactly are not listed.
You haven't specified db version so I'm assuming 11g - not tested, but I think it will give you the general idea:
SELECT * FROM (
WITH qry AS (
SELECT DISTINCT
order_id
,LISTAGG(product_id,'+')
WITHIN GROUP (ORDER BY product_id)
AS order_signature
FROM order_items
GROUP BY order_id)
SELECT order_id
,order_signature
,COUNT(DISTINCT order_id)
OVER (PARTITION BY order_signature)
count_same
FROM qry
) WHERE count_same > 1;
Limitation: it won't work if some orders are very big, e.g. 100s or 1000s of product IDs.
I'm not sure what your final data set needs to look like, but selecting from Customers with an EXISTS expression in the WHERE clause to look for order matches will get you there.