i have two tables, Tbought and Tsold
Tbought contains items i bought
ID |ItemName| PriceOfUnit | NumberOfItems I bought |DateIBought|
1 | tea | 3 | 6 |15/11/2015 |
2 | coffee | 5 | 4 |16/11/2015 |
3 | tea | 3 | 10 |20/12/2015 |
4 | juice | 5 | 15 | 1/1/2016 |
5 | coffee | 5 | 5 | 15/3/2016 |
6 | water | 5 | 2 | 16/4/2016 |
And Tsold contains items i sold
ID |ItemName| PriceOfUnit | NumberOfItems I sold |total sold $| PriceWhenBought|
1 | coffee | 7 | 6 | 30 | 5 |
2 | tea | 5 | 9 | 45 | 3 |
3 | coffee | 7 | 2 | 8 | 5 |
5 | juice | 6 | 11 | 55 | 5 |
if i bought coffee and price of unit was 5 that's in Tbought
now i sold coffee for 7 so my profit = 7 - 5 = 2
I need to calculate profit , so i thought i can get price of unit from Tbought -without entring it again in Tsold - and calculate my profit in Tsold table as above
How can i do that?
You'd do this by creating a query that joins both tables on ItemName, then you can calculate a field like Profit: Tsold.PriceOfUnit - Tbought.PriceOfUnit.
But there is a problem: "coffee" appears multiple times in Tbought. How can your query know which Tbought.PriceOfUnit to use if they are different?
EDIT
Then you first need a query to calculate the arithmetic mean per Item, it would look like this:
SELECT ItemName, Sum([PriceOfUnit]) / Count(*) AS AvgPriceBought
FROM Tbought
GROUP BY ItemName
Then join Tsold with this query on ItemName, and add a query field like this:
Profit: Tsold.PriceOfUnit - QAvgBought.AvgPriceBought
Related
I'm using SQL Server and I'm having a difficult time trying to get the results from a SELECT query.
I have 6 tables:
Product
Market
Seller
Buyer
Customer (data about customers - buyers and sellers)
Currency
select * from Product;
id(PK) | name_product
-------+--------------
1 | apple
2 | orange
3 | juice
select * from Market;
OrderID(PK) |SellOrderID(FK) | BuyOrderID(FK) | product-id
--------------+----------------+----------------+-----------
45 | 5 | 15 | 1
46 | 3 | 36 | 3
58 | 4 | 8 | 2
select * from Seller;
SellOrderID |id_seller(PK) | id_product
--------------+--------------+---------------------
5 | 5 | 1
3 | 3 | 3
4 | 2 | 2
select * from Buyer;
BuyOrderID |id_Buyer(PK) | id_product
--------------+--------------+---------------------
15 | 1 | 1
36 | 4 | 3
8 | 6 | 2
select * from Customer;
id_customer(PK) | name_customer
----------------+---------------
1 | Alice
2 | Sam
3 | Katy
4 | Soul
5 | Fab
6 | Yas
select * from Currency;
id_product(PK,FK) | currency(PK)
------------------*-------------
1 | EUR
2 | USD
3 | EUR
I'm looking to select the name of customers, their orders, the name of product bought and sold and the currency given to each product.
But I am not getting correct result. I want results as shown below:
name_customer | OrderID | name_product | currency(PK)
---------------+----------+--------------+-------------
Alice | 45 | apple | EUR
Sam | 58 | juice | EUR
Katy | 46 | orange | USD
Soul | 46 | apple | EUR
Fab | 45 | juice | EUR
Yas | 58 | orange | USD
Please advise
SELECT c.name_customer
,m.OrderID
,p.name_product
,cc.currency
FROM Customer c
INNER JOIN Buyer b ON b.id_Buyer = c.id_customer
INNER JOIN Market m ON m.BuyOrderID = b.BuyOrderID
INNER JOIN Product p ON p.id = m.product-id
INNER JOIN Currency cc ON cc.id_product = p.id
Hopefully it should work! If not please let me know.
I want to extract the products corresponding to each month having minimum and the maximum quantity. That is for month 1 the product having the least quantity that is "Butter" should be displayed along with the quantity and the product having the maximum quantity that is "Eggs" should be displayed.
Month Product Quantity
1 Bread 10177
1 Butter 5009
1 Coke 14381
1 Cookies 6892
1 Eggs 14783
2 Bread 10819
2 Butter 16156
2 Coke 23908
2 Cookies 9260
2 Eggs 10005
3 Bread 10933
3 Butter 4534
3 Cookies 488
3 Eggs 1744
4 Bread 12671
4 Butter 8982
4 Coke 9707
4 Cookies 3669
4 Eggs 19922
4 Yogurt 8063
5 Bread 14759
5 Coke 13346
5 Cookies 3139
5 Eggs 10137
5 Fruits 10961
6 Bread 14628
6 Butter 12447
6 Coke 9282
6 Cookies 19783
6 Eggs 6017
7 Bread 2573
7 Butter 20273
7 Coke 16162
7 Cookies 20156
7 Eggs 7678
8 Bread 7857
8 Butter 2529
8 Coke 10523
8 Cookies 3494
8 Eggs 4754
9 Bread 10382
9 Butter 9414
9 Coke 2714
9 Cookies 8602
9 Eggs 10772
10 Bread 4309
10 Butter 9253
10 Coke 17872
10 Cookies 14082
10 Eggs 14003
10 Fruits 9419
11 Bread 5308
11 Butter 6488
11 Coke 1998
11 Cookies 15450
12 Bread 7291
12 Butter 5968
12 Coke 8904
12 Cookies 12579
12 Eggs 4246
You can try to use MAX and MIN by month in subquery then self join
SELECT t2.*
FROM (
SELECT Month,
MAX(Quantity) maxQ,
MIN(Quantity) minQ
FROM T
GROUP BY Month
) t1 JOIN T t2 on t1.Month = t2.Month and (t2.Quantity = maxQ or t2.Quantity =minQ)
another way you can use exists subquery.
Query 1:
SELECT t2.*
FROM T t2
WHERE exists(
SELECT 1
FROM T t1
WHERE t1.Month = t2.Month
GROUP BY Month
HAVING
MAX(Quantity) = t2.Quantity
OR
MIN(Quantity) = t2.Quantity
)
Results:
| month | product | quantity |
|-------|---------|----------|
| 1 | Butter | 5009 |
| 1 | Eggs | 14783 |
| 2 | Coke | 23908 |
| 2 | Cookies | 9260 |
| 3 | Bread | 10933 |
| 3 | Cookies | 488 |
| 4 | Cookies | 3669 |
| 4 | Eggs | 19922 |
| 5 | Bread | 14759 |
| 5 | Cookies | 3139 |
| 6 | Cookies | 19783 |
| 6 | Eggs | 6017 |
| 7 | Bread | 2573 |
| 7 | Butter | 20273 |
| 8 | Butter | 2529 |
| 8 | Coke | 10523 |
| 9 | Coke | 2714 |
| 9 | Eggs | 10772 |
| 10 | Bread | 4309 |
| 10 | Coke | 17872 |
| 11 | Coke | 1998 |
| 11 | Cookies | 15450 |
| 12 | Cookies | 12579 |
| 12 | Eggs | 4246 |
You can use window function ROW_NUMBER() in a subquery to rank the records by quantity for each month, and filter out in the outer query on top and bottom products:
SELECT month, product, quantity
FROM (
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY month ORDER BY quantity) rn_asc,
ROW_NUMBER() OVER(PARTITION BY month ORDER BY quantity DESC) rn_desc
FROM mytable t
) x WHERE rn_asc = 1 OR rn_desc = 1
Window functions usually perform better than aggregation or correlated subqueries.
NB: if you want to allow top ties (and bottom ties), you can use RANK() instead of ROW_NUMBER().
Demo on DB Fiddle:
| month | product | quantity |
| ----- | ------- | -------- |
| 1 | Eggs | 14783 |
| 1 | Butter | 5009 |
| 2 | Coke | 23908 |
| 2 | Cookies | 9260 |
| 3 | Bread | 10933 |
| 3 | Cookies | 488 |
| 4 | Eggs | 19922 |
| 4 | Cookies | 3669 |
| 5 | Bread | 14759 |
| 5 | Cookies | 3139 |
| 6 | Cookies | 19783 |
| 6 | Eggs | 6017 |
| 7 | Butter | 20273 |
| 7 | Bread | 2573 |
| 8 | Coke | 10523 |
| 8 | Butter | 2529 |
| 9 | Eggs | 10772 |
| 9 | Coke | 2714 |
| 10 | Coke | 17872 |
| 10 | Bread | 4309 |
| 11 | Cookies | 15450 |
| 11 | Coke | 1998 |
| 12 | Cookies | 12579 |
| 12 | Eggs | 4246 |
I would use distinct on:
select *
from ((select distinct on (month) month, product, quantity
from t
order by month, quantity asc
) union all
(select distinct on (month) month, product, quantity
from t
order by month, quantity desc
)
) t
order by month, quantity;
select month, min(quantity) as least, max(quantity) as most
from products
group by month, product
will give you the product with minimum quantity for each month
I have an Orders table in the form:
| id | service_fee_cents | grand_total_cents | created_at |
|----|-------------------|-------------------|---------------|
| 1 | 1400 | 10000 | Jan 21 2018 |
| 2 | 1000 | 10000 | Feb 16 2018 |
| 3 | 500 | 10000 | March 21 2018 |
| 4 | 500 | 10000 | March 20 2018 |
And an Items table in the form
| id | order_id | title | price_cents | quantity |
|----|----------|--------|-------------|----------|
| 1 | 1 | lorem | 2000 | 2 |
| 2 | 1 | ipsum | 2030 | 1 |
| 3 | 2 | pie | 4000 | 4 |
| 4 | 3 | cheese | 6000 | 2 |
| 5 | 3 | burger | 7000 | 1 |
| 6 | 4 | custar | 1000 | 1 |
And I'm trying to run a SQL query to get a result in the form
| month | total_service_fee | total_grand_total | total_subtotal |
|-----------|-------------------|-------------------|----------------|
|2017-11-01 | 42 | 1,610 | 610 |
|2017-12-01 | 30 | 19,912 | 1,912 |
|2018-01-01 | 179 | 1,413 | 413 |
|2018-02-01 | 165 | 2,910 | 910 |
|2018-03-01 | 1,403 | 10,727 | 1,727 |
I've managed to get the first three columns using this query:
SELECT
date_trunc('month', created_at)::date AS month,
SUM(service_fee_cents) / 100 AS total_service_fee,
SUM(grand_total_cents) / 100 AS total_grand_total
FROM orders
GROUP BY month ORDER BY month
How do I get the last one? In the app, I get the sum via the following Ruby code:
order_subtotal = order.items.map{|item| item.price * item.quantity}.reduce(:+)
Which basically takes all the order's items, multiplies price by quantity and adds the results.
This should be a good start:
SELECT Date_trunc('month', created_at) :: DATE AS month,
SUM(service_fee_cents) / 100 AS total_service_fee,
SUM(grand_total_cents) / 100 AS total_grand_total,
SUM(total_subtotal) / 100 AS total_subtotals
FROM orders o
join (SELECT order_id,
SUM(price_cents * quantity) total_subtotal
FROM items i
GROUP BY order_id) i
ON o.id = i.order_id
GROUP BY month
ORDER BY month
You can get there by just joining the Orders table to the Items table and generating a SUM of subtotals by month. This may however be a somewhat expensive query to run if there are thousands of items in each order like you said.
SELECT
date_trunc('month', created_at)::date AS month,
SUM(service_fee_cents) / 100 AS total_service_fee,
SUM(grand_total_cents) / 100 AS total_grand_total,
SUM(price_cents * quantity) / 100 AS sub_total
FROM Orders o
JOIN Items i ON i.order_id = o.id
GROUP BY month ORDER BY month
http://sqlfiddle.com/#!15/555a2/1
So I have a table which I am using to store data for my documents. Now I want to calculate my sale over some period and let's say I have table like this now:
| productID | price | quantity |
| 30 | 15 | 5 |
| 30 | 15 | 3 |
| 20 | 13 | 2 |
| 20 | 13 | 3 |
| 30 | 12 | 4 |
| 30 | 16 | 1 |
| 15 | 1 | 2 |
| 10 | 3 | 5 |
So I need a SQL command that will multiply the price and quantity for every row separate (because as you can see, for some products I have different prices e.g. where product id is 30) and then sum all those values.
This will give you total sales for each product
SELECT productID,
Sum(Price * quantity) AS Total_sales
FROM yourtable
GROUP BY productID
I'm fairly new to SQL and am trying to get the price for a product transaction on a particular date my looking up the most recent price of that product prior to the transaction within a price catalog.
Specifically, I have the two following tables:
Transactions Catalog
----------------------------------------------------------------------------
ProductID | Design | Transaction_DT ProductID | Price | Effective_DT
1 | Plaid | 5/14/2016 1 | 20 | 4/22/2016
2 | Solid | 3/26/2016 1 | 10 | 5/2/2016
3 | PolkaDot | 4/12/2016 1 | 5 | 5/15/2016
4 | Solid | 4/24/2016 2 | 50 | 3/22/2016
5 | PolkaDot | 2/24/2016 2 | 25 | 4/1/2016
6 | PinStripe | 3/29/2016 2 | 10 | 4/2/2016
3 | 30 | 4/5/2016
3 | 25 | 4/9/2016
3 | 22 | 4/12/2016
4 | 12 | 3/15/2016
4 | 8 | 3/27/2016
4 | 6 | 4/25/2016
5 | 15 | 2/23/2016
5 | 11 | 2/25/2016
5 | 6 | 2/28/2016
6 | 26 | 2/2/2016
6 | 17 | 3/19/2016
6 | 13 | 5/16/2016
I have entered the following code:
SELECT Transactions.ProductID,
Catalog.Price,
Transactions.Transaction_DT,
Transactions.Design
FROM Transactions
LEFT JOIN
Catalog ON Transactions.ProductID = Catalog.ProductID AND
Catalog.Effective_DT = (
SELECT MAX(Effective_DT)
FROM Catalog
WHERE Effective_DT <= Transactions.Transactions DT
)
And obtained the following output:
ProductID | Price | Transaction_DT | Design
1 | Null | 5/14/2016 | Plaid
2 | 50 | 3/26/2016 | Solid
3 | 22 | 4/12/2016 | PolkaDot
4 | Null | 4/24/2016 | Solid
5 | 15 | 2/24/2016 | PolkaDot
6 | Null | 3/29/2016 | PinStripe
I would like to return the Price for products 1, 4, and 6 to be 10, 8, and 17 respectively (in addition to the correct prices which were properly output) instead of the Null values I'm getting. Any ideas on how I can obtain the proper results?
You forgot to filter the correlated query by the productID. You are not getting the correct latest date for the product. You need to use this query:
SELECT Transactions.ProductID,
Catalog.Price,
Transactions.Transaction_DT,
Transactions.Design
FROM Transactions
LEFT JOIN
Catalog ON Transactions.ProductID = Catalog.ProductID AND
Catalog.Effective_DT = (
SELECT MAX(Effective_DT)
FROM Catalog
WHERE Effective_DT <= Transactions.Transactions_DT
and ProductID = Transactions.ProductID
)