SQL Joining query using Selection - mysql

I have one table of tbl_order where columns are :
id_order
username
delivery_date etc...
and other table tbl_order_foods where columns are :
id_order
id_food
food_quantity etc
Here the sample pic of tbl_order table
and tbl_order_foods table
Here i am want to select all the foods with quantity with price and unit based on delivery_date.
Ex: Suppose On 2020-04-18 there are 3 orders where foods: tomato's are ordered total 15 kg (3 orders * 5 quantity * food_min_unit_amount * unit) and so on others foods.
how i can get the foodlist of total ordered quantity based on delivery_date

The method you need is the GROUP BY keyword.
SQL grouping works on the given attributes. According to your question this would be the delivery_date. In the projection (the attributes following the SELECT keyword) you then can use attributes you state after the GROUP BY keyword and aggregation functions e.g. SUM and MAX.
Based on your question you could get the total price for all orders on the given date like this:
SELECT order.delivery_date, SUM(food.food_quantity) as amount, SUM(food.food_total_price) as revenue
FROM tbl_order as order
INNER JOIN tbl_order_foods as food ON order.id_order = food.id_order
GROUP BY order.delivery_date
This would result in a list like this:
date | amount | revenue
------------------------
05.01| 10 | 800.00
I don't know whether this is what you wish. If you also want to split it into order positions then you would GROUP BY the food_name as well and add it to the projection which then results in the SUM grouped by the orders on a given day of a given product.
SELECT order.delivery_date, food.food_name, SUM(food.food_quantity) as amount, SUM(food.food_total_price) as revenue
FROM tbl_order as order
INNER JOIN tbl_order_foods as food ON order.id_order = food.id_order
GROUP BY order.delivery_date, food.food_name
Which would result in something like this.
date | food_name | amount | revenue
-----------------------------------
05.01| Tomato | 10 | 800.00
05.01| Apple | 5 | 400.00

Check out GROUP BY with the SUM function, a good article from Tutorialspoint.com is here. The only difference is that you are performing a JOIN to create the resulting table.
SELECT DISTINCT [f.id_food], [o.delivery_date], SUM(f.food_quantity) as [delivered_sum_qty], SUM(f.food_total_price) as [sum_food_total_price]
FROM tbl_order o LEFT JOIN tbl_order_foods f
ON [o.id_order] = [f.id_order]
GROUP BY [o.delivery_date];
If you need it, a pretty clear explanation of how to use JOIN is here as well.

Related

How to get value as header field in pivot table?

I've been looking for this answer for hours without finding anything at all on this subject.
I'm trying to get a pivot table from the "Sells" table that displays :
- as header fields, the name of each seller in my shop
- as rows, each month of the year
- as data the sum of their sells for each month
The only issue I have is that the headers are populated with ID instead of the name of the sellers.
For example, instead of showing this :
Month | Steve | Joe
January | 5000$ | 600$
February | 400$ | 400$
It keeps showing the ID related to each seller:
Month | 1 | 2
January | 5000$ | 600$
February | 400$ | 400$
Here is my query :
TRANSFORM Sum(Sells.Ca) AS [Monthly sells]
SELECT DISTINCTROW Format$(Sells.DateSold,'mm - mmmm') AS Month
FROM Sells
GROUP BY Sells.DateSold
PIVOT Sells.Seller
Thank you very much for your help and your time.
EDIT:
As #WolfgangKais mentionned in the comments, I forgot to mention that the Seller field is a lookup field, that's why it only shows the first value of the lookup field, hence the ID and not the name.
As stated by #June7 and #Wolfgang Kais, I had to include the Sellers Table in the query in order to get each seller's name instead of their ID, thank you very much for the lead.
This was done by :
Constructing a temporary table containing rows populated by sellers name, amount sold and date of sell:
SELECT Sellers.Name AS Seller, Sells.Ca AS Amount, Sells.DateSold AS Month
FROM Sells
INNER JOIN Sellers ON Sells.Seller = Sellers.ID
Including this temporary table into my first pivot query (In the FROM part):
TRANSFORM SUM(TempTable.Amount) AS [Monthly Sells]
SELECT Format$(TempTable.Month, 'mm - mmmm') AS Month
FROM(
SELECT Sellers.Name AS Seller, Sells.Ca AS Amount, Sells.DateSold AS Month
FROM Sells
INNER JOIN Sellers ON Sells.Seller = Sellers.ID
) AS TempTable
GROUP BY Temptable.Month
PIVOT Temptable.Seller

SQL scenario to group a dimension

I am using SQL and here is the scenario I am stuck with
Table A
SubscriptionID | Club | Sum_Of_Billings_Of_All_Month | EventID
Table B:
Cost | EventID
Table A left join Table B on EventID (To track the cost of each subscription)
Result
SubscriptionID | Club | Sum_Of_Billings_Of_All_Month | EventID | Cost
I want to break down the Sum_Of_Billings_Of_All_Month into per day billings. i.e. for each subscription, I want the breakdown of billings per day of the month. For that I will group by Sum_Of_Billings_Of_All_Month instead of subscriptionID.
Consequence
If I group by days of billing, upon joining I will get duplicates of subscriptionIDs and the eventIDs will be duplicated in rows multiple time which will then count the cost multiple times as well.
What I want:
In the same query, I want to be able to group by SubscriptionID so I can keep the unique subscriptions per row with their cost.
But one of the other requirement is that I want to know the breakdown of the billings as well to calculate the breakeven and other metrics in the same query
Here is the actual sample data
Table A
idCustomerSubscription | ClubID | EventId | BillingDate| FinalRevenue
33562784 | 56180001| 5y6m600np1fg | 5/31/2017 | 512
Table B
EventId |Cost
5y6m600np1fg |200
Table A join B left join on eventId (Group by SubscriptionID
idCustomerSubscription |ClubID |EventId |BillingDate| FinalRevenue | Cost
33562784 | 56180001 |5y6m600np1fg| 5/31/2017 | 512 |200
It serves the purpose because each subscription has one cost which is unique BUT it on the other hand, this kind of query will not give me breakdown of dates of billings (I need it for the breakeven calculation)
Table A join B left join on eventId (Group by billingdate
idCustomerSubscription| ClubID |EventId | BillingDate| FinalRevenue |Cost
33562784 | 56180001| 5y6m600np1fg |5/30/2017 |510 |200
33562784 | 56180001| 5y6m600np1fg |5/31/2017 |2 |200
This would give me the breakdown of the dates which i need for breakeven (510 on 30th and 2 on 31st) but it will make the cost duplicated (400 is the cost instead of 200)
I want to find out a SQL magic where I can keep the number of unique subcriptions per row and some way to track the billing dates of each subscriptions in the same query (without grouping it by date because it will make the rows duplicated). Is it possible ?
Perhaps some way where when the eventids are joined and its grouped by date, it doesnt duplicate the cost and count only one cost per eventid?
I hope you will get your desired result with below query. Try to modify your group by operation for mn (alias name) table.
select mn.idCustomerSubscription,mn.ClubID,mn.EventId,mn.BillingDate,mn.FinalRevenue,sq.cost
from tableA Mn left join (select idCustomerSubscription,max(cost) cost, min(billingDate) billingDate from tableA a left join tableB b on a.eventid=b.eventid group by idCustomerSubscription) sq on mn.idCustomerSubscription=sq.idCustomerSubscription and mn.billingDate=sq.billingdate
group by mn.idCustomerSubscription,mn.ClubID,mn.EventId,mn.BillingDate

Mysql Agregate function to select maximum and then select minimum price within that group

I am trying to get the maximum value out of a aggregate function, and then also get the min value out of a Price column which comes back in results.
id | discount | price
1 | 60 | 656
2 | 60 | 454
3 | 60 | 222
4 | 30 | 335
5 | 30 | 333
6 | 10 | 232
So in above table, I would like to separate Minimum Price vs Highest Discount.
This is the result I should be seeing:
id | discount | price
3 | 60 | 222
5 | 30 | 333
6 | 10 | 232
As you can see, its taken discount=60 group and separated the lowest price - 222, and the same for all other discount groups.
Could someone give me the SQL for this please, something like this -
SELECT MAX(discount) AS Maxdisc
, MIN(price) as MinPrice
,
FROM mytable
GROUP
BY discount
However, this doesnt separate the minimum price for each group. I think i need to join this table to itself to achieve that. Also, the table contains milions of rows, so the sql needs to be fast. One flat table.
This question is asked and answered with tedious regularity in SO. If only the algorithm was better at spotting duplicates. Anyway...
SELECT x.*
FROM my_table x
JOIN
( SELECT discount,MIN(price) min_price FROM my_table GROUP BY discount) y
ON y.discount = x.discount
AND y.min_price = x.price;
In your query, you cannot group by discount and then maximize the discount value.
This should get you the result you are looking for..
SELECT Max(ID) AS ID, discount, MIN(price) as MinPrice, FROM mytable GROUP BY discount
If you do not need the id, yo would do:
select discount, min(price) as minprice
from table t
group by discount;
If you want other columns in the row, you can either join back to the original table or use the substring_index()/group_concat() trick:
select substring_index(group_concat(id order by price), ',', 1) as id,
discount, min(price)
from table t
group by discount;
This will not always work because the intermediate result for group_concat() can overflow if there are too many matches within a column. This is controlled by a system parameter, which could be made bigger if necessary.

Join tables and preform aggregation on each of them

I have the following tables:
table part_list:
part_number | description | type
100 blablabla blabla
table part_list_supplier:
part_id | artikel
100 100100
100 200100
and I have this query:
select part_list.part_number, part_list.description, part_list.type, group_concat(coalesce(part_list_supplier.artikel, "nothing")) as "artikel"
from part_list
left join part_list_supplier on (part_list.part_number = part_list_supplier.part_id)
group by part_list.part_number;
this is the result:
part_number | description | type | artikel
100 blablablabla blabla 100100,200100
but I want to show the total stock per partnumber behind it. table receipt:
Number | import
100 5
100 10
table sales:
Number | sold
100 5
this is my query for one table:
SELECT SUM(sold) AS sold
FROM sales WHERE number = '".$partnumber.”'
but I want to calculate the stock per number and that must be shown behind the other results.
the full result:
part_number | description | type | artikel | stock
100 blablablabla blabla 100100,200100 10
The stock should be 10 because the total number of imports is 15 (5 + 10) and the total number of sales is 5.
I broke this up into pieces to solve it. I started by writing two queries, one that counted total receipt and one that counted total sales:
SELECT r.number, SUM(r.import) AS totalIn
FROM receipt r
GROUP BY r.number;
SELECT s.number, SUM(s.sold) AS totalOut
FROM sales s
GROUP BY s.number;
Then, I used those as two subqueries of a join to get the stock:
SELECT r.number, totalIn - totalOut AS stock
FROM(
SELECT r.number, SUM(r.import) AS totalIn
FROM receipt r
GROUP BY r.number) r
JOIN(
SELECT s.number, SUM(s.sold) AS totalOut
FROM sales s
GROUP BY s.number) s ON s.number = r.number;
Once I verfied this gave the proper stock, I was able to include those subqueries into your original query to build this:
SELECT pl.part_number, pl.description, pl.type,
GROUP_CONCAT(COALESCE(pls.artikel, "Nothing.")) AS artikel,
r.totalIn - s.totalOut AS stock
FROM part_list pl
LEFT JOIN part_list_supplier pls ON pls.part_id = pl.part_number
JOIN(
SELECT number, SUM(import) AS totalIn
FROM receipt
GROUP BY number) r ON r.number = pl.part_number
JOIN(
SELECT number, SUM(sold) AS totalOut
FROM sales
GROUP BY number) s ON s.number = r.number
GROUP BY pl.part_number;
Here is an SQL Fiddle example.
I may not be understanding your question properly, but can't you just add sum(sales.sold) to your select statement and join the sales table? E.g.:
select part_list.part_number, part_list.description, part_list.type, group_concat(coalesce(part_list_supplier.artikel, "nothing")) as "artikel", sum(sales.sold)
from part_list
left join part_list_supplier on (part_list.part_number = part_list_supplier.part_id)
left join sales on (part_list.part_number = sales.number
group by part_list.part_number;

merging two queries

I have a table of recipes, and I want to show a weekly value for each of them. The values are votes cast for them. My problem is that I want to make an excel-like table with all available fridays on my db, add a column for each recipe, and put it's value for the friday on that column, if any value exists.
Now apparently the easiest join doesn't work so I wrote two queries: one to get all ids for my recipes and one for the values to show. The first (MySql) query is just a select id from recipes, the second is like this:
select d.date,perc from
(SELECT date FROM weekly where YEAR(date)=2014 group by date) as d
left join weekly on d.date = weekly.date and weekly.id_rec= :idrec
Any idea how to merge those two queries? Running two queries makes everything slow down, but when I tried to merge them I didn't get the correct results.
Data:
sql fiddle
The result should be something like:
Dates | Recipe A | Recipe B | ...
Date 1 | 0.005 | 0.11 |
Date 2 | 0 | 0 |
Date 3 | 0 | 0.1 |
Note that Date 2 doesn't exist for Recipe A and B, but for some other do.
You should be able to merge the two queries like this:
SELECT recipes.id, votes.date, votes.perc FROM recipes
RIGHT JOIN
(select weekly.id_rec, d.date, perc from
(SELECT weekly.id_rec, date FROM weekly where YEAR(date) = 2014 group by date) as d left join weekly on d.date = weekly.date) as votes
ON votes.id_rec = recipes.id
SQL Fiddle