How to select and count data from three tables in mysql - mysql

I have three tables
1 - Products
2- Orders
3- Order_item
Table (Products)
ID | Product_name |
--------------------
1 | Samsung Galaxy
Table (Orders)
ID | Client_name
-------------------
1 | Admin
Table (Orders_item)
ID | Order_ID | Product_ID | Quantity
-------------------------------------
1 | 1 | 1 | 1
2 | 1 | 1 | 1
3 | 1 | 1 | 1
I want to select product name , client name and number of quantities when order is 1. I have tried this query
SELECT products.name,orders.order_id,orders.client_name,order_item.quantity COUNT(*) FROM products,orders,order_item WHERE products.id = order_item.product_id AND orders.order_id = order_item.order_id AND orders.order_id=1
Which returns result like
Name | Order_ID | Client_name | Quantity
----------------------------------------
Sa..| 1 | Admin | 1
Sa..| 1 | Admin | 1
Sa..| 1 | Admin | 1
I want to get the the result like
Samsung | 1 | Admin | 3
Someone please help me .

You need a GROUP BY
SELECT products.Product_name AS Name,
orders.id AS Order_ID,
orders.client_name AS Client_name,
SUM(order_item.Quantity) AS Quantity
FROM products
LEFT JOIN order_item
ON order_item.Product_ID = products.ID
LEFT JOIN orders
ON orders.ID = order_item.Order_ID
WHERE orders.id=1
GROUP BY products.Product_name,
orders.id,
orders.client_name
This outputs :
| Name | Order_ID | Client_name | Quantity |
| -------------- | -------- | ----------- | -------- |
| Samsung Galaxy | 1 | Admin | 3 |
Note that JOIN can be a good reading too.

Related

Mysql fetch rows limited be another table column value

I have list of products and seller who added this products
Each Seller has a limit to show the products.
I need to write a query to list all the products with pagination 100 and show only seller products limited to that seller
`Seller Table`
| seller id| Seller Name | limit |
|:-------- |:-----------:| ------:|
| 1 | Seller One | 1 |
| 2 | Seller Two | 3 |
| 3 | Seller Three| 2 |
`Products Table
| product id| seller id | Product Name |
|:-------- |:----------:| ------------:|
| 1 | 1 | Product 1 |
| 2 | 2 | Product 2 |
| 3 | 1 | Product 3 |
| 4 | 1 | Product 4 |
| 5 | 2 | Product 5 |
| 6 | 2 | Product 6 |
| 7 | 2 | Product 7 |
| 8 | 3 | Product 8 |
| 9 | 3 | Product 9 |
| 9 | 3 | Product 10 |
| 9 | 3 | Product 11 |
(Output or Result I am expecting)
| product id| seller id | Product Name |
|:-------- |:----------:| ------------:|
| 1 | 1 | Product 1 |
| 2 | 2 | Product 2 |
| 5 | 2 | Product 5 |
| 6 | 2 | Product 6 |
| 8 | 3 | Product 8 |
| 9 | 3 | Product 9 |
Seller 1 = Product 1
Seller 2 = Product 2 , Product 5 and Product 6
Seller 3 = Product 8 and Product 9
I want to get this products
How do I write a query?
and also is it possible to selected random products of the seller
I have query only to fetch only the products.
$products = Products::paginate(100);
```
I need modify it based on Seller Model
Enable WHERE clause when searching particular seller and product otherwise disable it. Use LIMIT and OFFSET for pagination. Please try this
-- MySQL (v5.8)
SELECT t.product_id, s.seller_id, t.product_name
FROM seller s
INNER JOIN (SELECT product_id
, seller_id
, product_name
, ROW_NUMBER() OVER (PARTITION BY seller_id ORDER BY product_id) row_num
FROM Products
-- WHERE seller_id = 1
-- AND product_id = 1
) t
ON s.seller_id = t.seller_id
AND t.row_num <= s.t_limit;
Please check from url https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=d142f50fb24763ec9fc1e937f8b8d6a7
If needed comma separated product_name then try this one
SELECT CONCAT(MAX(s.seller_name), ' = ', GROUP_CONCAT(t.product_name)) expected_output
FROM seller s
INNER JOIN (SELECT product_id
, seller_id
, product_name
, ROW_NUMBER() OVER (PARTITION BY seller_id ORDER BY product_id) row_num
FROM Products
-- WHERE seller_id = 1
-- AND product_id = 1
) t
ON s.seller_id = t.seller_id
AND t.row_num <= s.t_limit
GROUP BY s.seller_id;
Please check from https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=0e4cfa7dbb744e7aa416b79d6f964775
As per #RahulBiswas sql code I wrote a Laravel Query. It is working
$subq = Products::select(DB::raw('ROW_NUMBER() OVER (PARTITION BY seller_id ORDER BY id) row_num, *'));
$query = Sellers::select('t.*',)->join(\DB::raw('('.$subq->toSql().') as t'), function ($join) use ($subq) {
$join->on('sellers.user_id','t.seller_id')
$join->on('t.row_num', '<=', "sellers.limit")
})

Retrieving last record of a table inside inner join

I have these three tables:
products
+----+--------+
| id | QRCode |
+----+--------+
| 1 | 1000 |
| 2 | 1001 |
+----+--------+
prices
+----+---------+------------+
| id | price | product_id |
+----+---------+------------+
| 2 | $100001 | 1 |
| 3 | $100002 | 1 |
| 4 | $90001 | 2 |
| 5 | $90002 | 2 |
+----+---------+------------+
colors
+----+--------+-------------+
| id | color | product_id |
+----+--------+-------------+
| 1 | ffffff | 1 |
| 2 | f2f2f2 | 1 |
| 4 | aaaaaa | 2 |
| 5 | a3a3a3 | 2 |
+----+--------+-------------+
I would like to merge these three in a way that returns:
group_concat colors based on product_id
retrieves last record of each grouped price
This is the desired output:
+--------+----------------+-------------+-------------+
| QRCode | colors | price | product_id |
+--------+----------------+-------------+-------------+
| 1000 | ffffff, f2f2f2 | $100002 | 1 |
| 1001 | aaaaaa, a3a3a3 | $90002 | 2 |
+--------+----------------+-------------+-------------+
Things I tried:
The query below returns product_id of last record of each grouped price
SELECT product_id FROM price where id IN
(SELECT max(id) FROM price
GROUP BY product_id)
Then I tried to put query above in this query as a subquery
SELECT products.QRCode, priceSubQ.price, GROUP_CONCAT(colors.color) as colors FROM products
INNER JOIN colors on colors.product_id = products.id
INNER JOIN ( /* I put query above here */ ) as priceSubQ ON priceSubQ.product_id = products.id
GROUP BY products.id
What am I doing wrong?
I came across this link which helped me understand the problem
Changed inner query to:
SELECT product_id FROM ANY_VALUE(price) where id IN
(SELECT max(id) FROM price
GROUP BY product_id) group by product_id
solved my problem.
Something like the following should work (not tested)..
SELECT
products.QRCode,
priceSubQ.price,
GROUP_CONCAT(colors.color) as colors
FROM
products
LEFT JOIN colors
ON colors.product_id = products.id
LEFT JOIN (
SELECT
MAX(p1.id) as p1maxId,
p2.price AS price,
p2.product_id AS product_id
FROM
prices p1
INNER JOIN prices p2
ON p1.p1maxId = p2.id
GROUP BY
p1.product_id
) AS priceSubQ
ON priceSubQ.product_id = products.id
GROUP BY
products.id

select from multiple child tables in sql

I have 3 table, 1 is the parent table and 2 child tables.
1st table contains all the order numbers and other 2 child table contains the order details for the order numbers
example
table Order_master
order_id | order_date | order_status
-------------------------------------
1 | 20-10-15 | pending
------------------------------------
2 | 10-11-15 | closed
------------------------------------
3 | 15-11-15 | closed
------------------------------------
4 | 25-12-15 | pending
------------------------------------
5 | 27-12-15 | closed
------------------------------------
Child Table order_detail
-------------------------------------
id | order_id | client_name
-------------------------------------
1 | 1 | Abc company
------------------------------------
2 | 3 | Test company
Child Table order_detail_cc
-------------------------------------
id | order_id | client_name
-------------------------------------
1 | 2 | XYZ company
------------------------------------
2 | 4 | A2 company
------------------------------------
3 | 5 | B2 company
------------------------------------
now i want to get the results as
-------------------------------------
order_id | order_date | client_name
-------------------------------------
1 | 20-10-15 | Abc company
------------------------------------
2 | 10-11-15 | XYZ company
------------------------------------
3 | 15-11-15 | Test company
------------------------------------
4 | 25-12-15 | A2 company
------------------------------------
5 | 27-12-15 | B2 company
------------------------------------
please help
MySQL Union manual
SELECT Order_master.order_date, Order_master.order_date, u.client_name
FROM Order_master
JOIN (
(SELECT order_id, client_name
FROM order_detail)
UNION
(SELECT order_id, client_name
FROM order_detail_cc)
) u ON Order_master.order_id = u.order_id
SELECT order_id, order_date, client_name
FROM order_detail
JOIN order
USING (order_id)
UNION ALL
SELECT order_id, order_date, client_name
FROM order_detail_cc
JOIN order
USING (order_id)

Implementing a complex query in MySQL

I have 3 tables:
table products
table sub products
table stock.
I want to join these tables like in the result table below. In fact, I want All products that have least price and have count greater than zero and inserted as latest records!
How can I do the query?
more explain:
table product
----------------------------------
pid | title | desc | content |
----------------------------------
1 | lumia 920| ..... | ...... |
----------------------------------
2 | galaxys6 | .... | ...... |
----------------------------------
table sub_product
------------------------
subid |pid| name |
------------------------
1 | 1 | yellow |
------------------------
2 | 1 | black |
------------------------
3 | 2 | 32 GB |
table stock
-----------------------------------------------
sid |subid| price | count | inserted_date |
-----------------------------------------------
1 | 1 | 100 | 5 | 2015-01-01 |
-----------------------------------------------
2 | 1 | 150 | 9 | 2015-01-02 |
-----------------------------------------------
3 | 1 | 100 | 0 | 2015-02-02 |
-----------------------------------------------
4 | 2 | 111 | 1 | 2015-02-21 |
-----------------------------------------------
5 | 3 | 50 | 7 | 2015-02-01 |
-----------------------------------------------
6 | 3 | 10 | 4 | 2015-03-06 |
-----------------------------------------------
7 | 3 | 400 | 9 | 2015-06-06 |
-----------------------------------------------
table result
------------------------------------------------------------
pid |subid| title | name | price | count | inserted_date
------------------------------------------------------------
1 | 2 |lumia 920| black | 111 | 1 | 2015-02-21
------------------------------------------------------------
2 | 3 |galaxy s6| 32 GB | 10 | 4 | 2015-03-06
------------------------------------------------------------
as you see in product table we have two items lumia 920 and galaxy s6
and in sub_product we have 3 items that related to products.
also in stock I saved all modication of price and count of each item
so I want return latest modification of each sub_product as current state of it sub_prodct that has least price as result
but if count was zero should return another sub_product with mentioned conditions.
Select * From stock s Join sub_product sp On s.sub_productid = sp.sub_productid Join product p On p.productid = sp.productid
Where s.counte > 0 And s.date_insert in (Select MAX(date_insert) as d From stock ss
where s.sub_productid = ss.sub_productid group by sub_productid)
This query will return the all products that have least price and have count greater than 0 and latest records.
SELECT p.pid, sp.subid, p.title, sp.name, s.price, s.count, s.inserted_date
FROM product p
INNER JOIN sub_product sp ON sp.pid = p.pid
INNER JOIN stock s ON s.subid = sp.subid
WHERE s.count > 0
GROUP BY p.title
ORDER BY s.inserted_date DESC, s.price ASC
Try something like this:
SELECT prod.title, prod.desc, subProd.spid, subProd.pid, subProd.name, stk.price, stk.discount, stk.count, stk.inserted_date
FROM products AS prod
INNER JOIN sub_products AS subProd ON prod.pid = subProd.pid
INNER JOIN stock AS stk ON subProd.spid = stk.spid
AND stk.count > 0
AND stk.spid = (select spid from stock order by inserted_date desc limit 1)

Group by id, but order by name

I have a table like this (created from joining different tables)
+------------+--------------+-------------+
| product_id | product_name | category_id |
+------------+--------------+-------------+
| 1 | orange | 3 |
| 1 | orange | 4 |
| 2 | banana | 2 |
| 3 | apple | 2 |
| 3 | apple | 3 |
| 3 | apple | 4 |
+------------+--------------+-------------+
I'd like it grouped together by ID, but sorted by name.
Like this
+------------+--------------+-------------+
| product_id | product_name | category_id |
+------------+--------------+-------------+
| 3 | apple | 2 |
| 3 | apple | 3 |
| 3 | apple | 4 |
| 2 | banana | 2 |
| 1 | orange | 3 |
| 1 | orange | 4 |
+------------+--------------+-------------+
Is this possible? I tried using GROUP BY, but then it only keeps one row per product, so I can't see all the categories a product.
edit: My query so far
SELECT products.id as product_id, products.name as product_name, categories.id as category_id
FROM produkte
LEFT JOIN prod_cat ON products.id = prod_cat.product_id
JOIN categories ON prod_cat.category_id = categories.id
ORDER BY products.id
With "prod_cat" being the table that assigns categories to products.
This will order them by name then category id, giving the results as you have shown them.
SELECT products.id as product_id, products.name as product_name, categories.id as category_id
FROM produkte
LEFT JOIN prod_cat ON products.id = prod_cat.product_id
JOIN categories ON prod_cat.category_id = categories.id
ORDER BY product_name ASC, category_id ASC
I think you've misunderstood GROUP BY, but if you want to group them (reduce records to one where the field given in the GROUP BY clause matches), you can show the categories as a list using GROUP_CONCAT(categories.id) with GROUP BY product_id
Select * from products order by product_id desc, product_name asc;