Table Data:
sales_products table data:
product_id
quantity
sales price
1
4
300
1
5
300
2
3
400
2
2
400
3
3
100
products table
id
product_name
1
product_x
2
product_y
3
product_z
Expected Query Output
product_name
Quantity
Total_Price
product_x
9
2700
product_y
5
2000
product_z
3
300
I was trying with following Query and didn't get expected output
$invoiceDetails = DB::table('products')
->join('sales_products', 'sales_products.product_id', '=', 'products.id')
->select(
'products.product_name',
'sales_products.quantity',
'sales_products.sales_price',
DB::raw('(sales_products.quantity * sales_products.sales_price) as total')
)
->where('sales_products.invoice_id', '=', $id)
->get();
SELECT p.product_name, sp.Quantity, sp.Total_price
FROM `products` p
INNER JOIN (
SELECT SUM(quantity) AS Quantity,
product_id,
SUM(sales_price*quantity) AS Total_price
FROM `sales_products`
GROUP BY product_id
) AS sp
ON p.id = sp.product_id
This query above should help. How you should merge queries is by using GROUP BY. Using GROUP BY on the first table wrt to the product_id helps us sum up the columns accordingly.
Related
I have a table that I want to select product_name with lowest/min price the following:
product_name | price
Cat | 12
Dog | 21
Cat | 14
Dog | 20
Fish | 10
Fish | 3
THE DESIRE Output should be
Cat | 12
Dog | 20
Fish | 3
BELOW IS MY SQL QUERY
$products = DB::table('products')
->orderBy('products.products_price', 'asc')
->groupBy('products.products_name')
->get();
When I used this script, it only shows the highest/max price, not the lowest price
You need an aggregate instead of ordering. For Laravel, that means passing in the columns along with a DB::raw:
$products = DB::table('products')
->orderBy('products.products_price', 'asc')
->groupBy('products.products_name')
->select(['product_name', DB::raw('min(price) as price')])
->get();
Edit for ID
Taking off the answer here : SQL: Group by minimum value in one field while selecting distinct rows the mysql query would be
SELECT p1.*
FROM products p1 INNER JOIN
(
SELECT product_name, MIN(price) AS as min_price
FROM products
GROUP BY product_name
) p2 ON p1.product_name = p2.product_name AND p1.price = p2.min_price
Now we have to convert it to Query Builder
$products = DB::table('products AS p1')
->join(DB::raw('(
SELECT product_name, MIN(price) AS as min_price
FROM products
GROUP BY product_name
) AS p2'),
function($join)
{
$join->on('p1.product_name', '=', 'p2.product_name');
$join->on('p1.price', '=', 'p2.min_price');
})
->get(['p1.id', 'p1.product_name', 'p1.price']);
This has not been tested, so I hope it works
Problem:
You are not defining that the price attribute should be aggregated to a minimum.
Solution:
If you want the max price you need to select the MIN() aggregation.
You can do this by using ->selectRaw('MIN(price) as max_price').
Please Note:
If you want other attributes also selected simply add them comma separated.
->selectRaw('name, MAX(price) as max_price')
#edit
Do you still use the oderBy? If not, try it with orderBy('products.products_price', 'ASC')
I'm working with PHP and MySQL, and I need to SUM the total amount of products joining 3 tables:
order_products: (There are multiple order products with the same name but different amounts in the table)
order_id (int)
product_name (varchar)
product_amount (int)
orders:
order_id (int)
order_date (varchar)
order_status (varchar)
supplier:
product_name (varchar)
product_amount (int)
So, I want to show how many products I sold and status is shipped and how many I ordered from the supplier in one single row. Any of two examples below will help me to achieve my goal.
Like:
Product Name (sum order_products) (sum supplier) Order status
first product 300 2500 Shipped_Only
second product 50 400 Shipped_Only
third product 10 600 Shipped_Only
Product Name (sum order_products) (sum supplier) Order status
first product 2200 2500 Not_Shipped
second product 400 400 Not_Shipped
third product 590 600 Not_Shipped
Are there any examples or other help that I can get to do this?
Edit:
Sample Data goes like this
order_products:
order_id product_name product_amount
255 product 1 200
256 product 1 100
257 product 2 50
258 product 3 10
orders:
order_id order_date order_status
255 09.05.2018 Shipped
256 09.05.2018 Shipped
257 10.05.2018 Not_Shipped
258 10.05.2018 Not_Shipped
supplier:
product_name product_amount
product 1 2500
product 2 400
product 3 600
You should use a join on the aggregated subselect.
SELECT t1.product_name, t1.sum_order_products, t2.supplier_sum, t1.order_status
FROM (
SELECT op.product_name, SUM(op.product_amount) sum_order_products, o.order_status
FROM order_products op
INNER JOIN orders o ON op.order_id = o.order_id
WHERE o.order_status = 'Shipped'
GROUP BY op.product_name, o.order_status
) t1
LEFT JOIN (
SELECT s.product_name, SUM(s.product_amount) supplier_sum
FROM supplier s
GROUP BY s.product_name
) t2 ON t1.product_name = t2.product_name
ORDER BY t1.order_status, t1.product_name
From What I understand, I think this is what you want, please give more clarity if this is not what you are expecting.
You will need to use GROUP BY clause and them you will have to use count() function to count the number of rows for the results coming from Group By Clause. I am writing an example of how to use a group by clause, you will need to modify the query as per your need.
SELECT
order_products.product_name,
count(*) as Total_Orders,
MAX(supplier.product_amount) as Supplier_Amt,
orders.order_status
FROM supplier
INNER JOIN order_products ON supplier.product_name = order_products.product_name
INNER JOIN orders ON orders.order_id = order_products.order_id
WHERE orders.order_status = 'Not_Shipped'
GROUP BY order_products.product_name, orders.order_status;
You will need to queries, you can write the other one, just replace WHERE orders.order_status = 'Not_Shipped' with WHERE orders.order_status = 'Shipped' Also if you want all in a single query, simply remove the where clause.
I've a problem in laravel query:
I wanna to order by before group by of same columns,
for example:
Products table
id ....... cat_id ....... color_id ....... count<br>
---------------------------------------------------------<br>
1 ........... 27 ............... 3 ............... 0
<br>
2 ........... 27 ............... 7 ................ 3
<br>
3 ........... 27 ............... 3 ................ 10
<br>
4 ........... 27 ............... 3 ................ 2
now: I wanna down result with first orderby 'count' so groupby 'cat_id,color_id':
id ....... cat_id ....... color_id ....... count<br>
---------------------------------------------------------<br>
3 ........... 27 ............... 3 ............... 10
<br>
2 ........... 27 ............... 7 ................ 3
Assuming your Query looks like
SELECT id, cat_id, color_id, count FROM products
and count is a value from the DB, you can just combine GROUP BY and ORDER BY statements:
SELECT id, cat_id, color_id, count FROM products GROUP BY cat_id, color_id ORDER BY count
With this Query a lot of results are lost. If you want to combine the values for lets say count you could use GROUP_CONCAT:
SELECT id, cat_id, color_id, GROUP_CONCAT(count) FROM products GROUP BY cat_id, color_id ORDER BY count
With this Query, you will still get all relevant information, but for every entry in columns cat_id and color_id you will get a comma-seperateted string of the values for count.
Here some links for further information from w3schools:
GROUP BY
ORDER BY
please try this
select pr_l.*
from products pr_l
inner join (
select
cat_id, color_id,max(count) as count
from products
group by `cat_id`,`color_id`
) pr_r
on pr_l.count = pr_r.count and pr_l.cat_id = pr_r.cat_id and pr_l.color_id = pr_r.color_id
order by count desc
normally 'order by' before 'group by' is not working . so that i have used inner join for products table
left products table has all records and right products table has maximum count row with group by cat_id and color_id
for laravel sql syntax
$products = $products->select(DB::raw('pr_l.*'))->from(
DB::raw('inner join (
select
cat_id, color_id,max(count) as count
from products
group by `cat_id`,`color_id`
) pr_r')
)->where(pr_l.count = pr_r.count and pr_l.cat_id = pr_r.cat_id and pr_l.color_id = pr_r.color_id)->orderBy('count', 'desc');
how to convert:
select l.*
from products l
inner join (
select
cat_id, color_id,max(count) as count
from products
group by `cat_id`,`color_id`
) r
on l.count = r.count and l.cat_id = r.cat_id and l.color_id = r.color_id
order by count desc
to laravel elequent syntax looklike down:
$products = $products->select(DB::raw('l.*'))->from(
DB::raw('inner join (
select
cat_id, color_id,max(count) as count
from products
group by `cat_id`,`color_id`
) r')
)->where(l.count = r.count and l.cat_id = r.cat_id and l.color_id = r.color_id)->groupBy(['products_id','color'])->orderBy('count', 'desc');
Can someone help me how to make an efficient mysql query for this?
I need to make a query to get the sum quantity of all ordered items.
combined with.
I need to make a query to get the sum quantity of all received items.
Please note that some products have serial numbers when received and some don't in my 'received_po_details' table. That's where I'm having problem with since the sum of received gets doubled because of the serial numbers.
Table: received_po_details
i_rpoh_id i_p_id i_quantity_received s_product_serial
1 1 100
1 2 100
1 3 50
1 4 25
1 7 100
1 8 50
1 6 1 XYZ1
1 6 1 XYZ2
1 5 1 ABC1
1 5 1 ABC2
Right now I have these 2 separate sql that I need to combine.
I don't want to use Union statement for this if possible...
-- to get the Total Quantity Ordered
SELECT
products.i_id AS 'ID',
products.s_name AS 'Name',
COALESCE(SUM(purchase_order_details.i_quantity_ordered),0) AS 'Total Quantity Ordered'
FROM
products
LEFT JOIN
purchase_order_details
ON
products.i_id = purchase_order_details.i_p_id
GROUP BY
products.i_id
-- to get the Total Quantity Received
SELECT
products.i_id AS 'ID',
products.s_name AS 'Name',
COALESCE(SUM(received_po_details.i_quantity_received),0) AS 'Total Quantity Received'
FROM
products
LEFT JOIN
received_po_details
ON
products.i_id = received_po_details.i_p_id
GROUP BY
products.i_id
You can combine these queries by creating a derived table or each type of sum (in the query below they're named t1 and t2) and left joining the derived tables to the main product table.
SELECT
p.i_id AS 'ID',
p.s_name AS 'Name',
COALESCE(t1.total,0) 'Total Quantity Ordered',
COALESCE(t2.total,0) 'Total Quantity Received'
FROM products p
LEFT JOIN (
SELECT
pod.i_p_id,
SUM(pod.i_quantity_ordered) total
FROM purchase_order_details pod
GROUP BY pod.i_p_id
) t1 ON t1.i_p_id = p.i_id
LEFT JOIN (
SELECT
rpd.i_p_id,
SUM(rpd.i_quantity_received) total
FROM received_po_details rpd
GROUP BY rpd.i_p_id
) t2 ON p.i_id = t2.i_p_id
I have table Orders:
O_Id OrderDate OrderPrice Customer
1 2008/11/12 1000 Hansen
2 2008/10/23 1600 Nilsen
3 2008/09/02 700 Hansen
4 2008/09/03 300 Hansen
5 2008/08/30 2000 Jensen
6 2008/10/04 100 Nilsen
and query:
SELECT COUNT(Customer) AS CustomerNilsen FROM Orders
WHERE Customer='Nilsen'
but is possible add to this results IDs results?
I would like receive
count: 2
and
ids: 2 and 6
GROUP_CONCAT may help:
SELECT
COUNT(Customer) AS CustomerNilsen,
GROUP_CONCAT(O_Id) as IDS
FROM
Orders
WHERE
Customer='Nilsen'
Better to just fetch all the IDs and then use the appropriate row count function:
SELECT `O_Id` FROM `Orders`
WHERE `Customer` = 'Nilsen'
I don't really understand your question, but from what I can tell you just want to SELECT the o_id column in your query:
SELECT COUNT(Customer) AS CustomerNilsen, O_Id AS OrderID FROM Orders WHERE Customer='Nilsen'
You might check this
SELECT Customer,
COUNT(Customer) AS CustomerNilsen
FROM Orders
WHERE Customer = 'Nilsen'
GROUP BY Customer
HAVING CustomerNilsen = 1
Try this
SELECT O1.O_Id AS OrderID,Count(O1.O_Id) AS OrderCount FROM Orders O1
INNER JOIN Orders O2 ON O1.Customer = O2.Customer
WHERE O1.Customer='Nilsen'
GROUP BY O1.Customer,O1.O_Id