Mysql fetch rows limited be another table column value - mysql

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")
})

Related

How to select and count data from three tables in 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.

select sum() from multiple table with same column

I have a table for product, sales_item and a stock with following structure
Product table:
+----+-----+-------------+
| id |name |description |
+----+-----+-------------+
| 1 |Pr1 |prod1 |
+----+-----+-------------+
| 2 |Pr2 |prod2 |
+----+-----+-------------+
| .. |... |..... |
+----+-----+-------------+
sales_item_details table
+-----+----------+------------+-----+
| id | sales_id | product_id | qty |
+-----+----------+------------+-----+
| 517 | 211 | 1 | 200 |
+-----+----------+------------+-----+
| 518 | 211 | 1 | 120 |
+-----+----------+------------+-----+
and production
+----+------------+-------+
| id | product_id | qty |
+----+------------+-------+
| 1 | 1 | 20 |
| 2 | 2 | 200 |
| 3 | 1 | 20 |
| 4 | 3 | 30 |
| 5 | 9 | 30 |
| 6 | 65 | 10 |
| 7 | 65 | 50 |
| 8 | 71 | 10 |
| 9 | 71 | 10 |
| 10 | 71 | 10 |
+----+------------+-------+
And now I am creating multiple database with same table defination and need to maintain stock
production table and product table will be maintained from single database
only sales_item_details table will be different but product id will same
So how will be the query to get SUM(qty) of sales item details and view the inventory in stock
I have tried this:
SELECT
`pr`.`id`,
`pr`.`name`,
sl.size,
IFNULL(SUM(s.qty), 0) AS sales,
IFNULL((SELECT SUM(qty) FROM production st WHERE st.product_id = `pr`.`product-id`), 0) AS stock_added
FROM products pr
LEFT JOIN (
SELECT qty, product_id FROM db1.sales_item_details
UNION ALL
SELECT qty, product_id FROM db2.sales_item_details
) s ON pr.`id` = s.product_id
LEFT JOIN size_list sl ON sl.id = `pr`.`product-size`
GROUP BY s.product_id
ORDER BY sales DESC
but getting the product which is sold
Any help will be appriciated
1st I created a view holding all sales items grouped by product id in the main database:
CREATE OR REPLACE VIEW unit_sold_all AS
SELECT
p.`product-id` AS product_id,
(
(SELECT IFNULL(SUM(s0.qty), 0) FROM db_1.sales_item_details s0 WHERE s0.product_id = p.`product-id`) +
(SELECT IFNULL(SUM(s1.qty), 0) FROM db_2.sales_item_details s1 WHERE s1.product_id = p.`product-id`) +
(SELECT IFNULL(SUM(s2.qty), 0) FROM db_3.sales_item_details s2 WHERE s2.product_id = p.`product-id`) +
(SELECT IFNULL(SUM(s3.qty), 0) FROM db_4.sales_item_details s3 WHERE s3.product_id = p.`product-id`) +
(SELECT IFNULL(SUM(s4.qty), 0) FROM db_5.sales_item_details s4 WHERE s4.product_id = p.`product-id`)
) as total_unit_sales
FROM products p
Then in another sql, I selected the sum of the sales.
PS: I answered this question myself because this might need by another person in the future.

Sum data from same table based on another column id's

I have table that looks like this
+-----------+----------+----------+
| ProductID | ShopID | Quantity |
+-----------+----------+----------+
| 1 | 1 | 10 |
| 2 | 1 | 10 |
| 3 | 1 | 15 |
| 1 | 2 | 25 |
| 4 | 1 | 5 |
| 2 | 2 | 6 |
| 4 | 3 | 7 |
+-----------+------------+--------+
And I need to get sum of quantity from multiple shops for single product.
For example: sum of quantity for ProductID 1 from ShopID 1 and 2.
So result for that would be 35.
Is it possible to do that in single query?
you need to group by product id
select sum(Quantity) as total from TableName
where ProductID =1 and ShopID in (1,2)
group by ProductID
Use Sum aggregate function on Quantity column and use the needed condition on productid and shopid.
select sum(Quantity) as Total_Quantity from YourTableName
where ProductID = 1 and ShopID in (1,2)

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)

MySQL Order results by field uniquness

I have a website listing products from various vendors (hundreds of different vendors). When you search for a specific product I return a bunch of products which can be sorted by price, etc.
I want the default sort that I show the user to showcase as many unique vendors as possible, without using groupby and removing multiple products from the same user.
So if a given search query returns 10 products from vendor a, 5 products from vendor b, 5 products from vendor C, etc -- the default sort would be to show one from each of them (in any order, really), and then the rest of the results.
EDIT: example dataset:
+----+-----------+--------------+
| id | vendor_id | product_name |
+----+-----------+--------------+
| 1 | 1 | Product 1 |
| 2 | 1 | Product 2 |
| 3 | 1 | Product 3 |
| 4 | 2 | Product 4 |
| 5 | 2 | Product 5 |
| 6 | 2 | Product 6 |
| 7 | 3 | Product 7 |
| 8 | 3 | Product 8 |
| 9 | 3 | Product 9 |
+----+-----------+--------------+
Desired Results:
+----+-----------+--------------+
| id | vendor_id | product_name |
+----+-----------+--------------+
| 1 | 1 | Product 1 |
| 4 | 2 | Product 4 |
| 7 | 3 | Product 7 |
| 2 | 2 | Product 2 | * any sort after initial unique results*
| 3 | 2 | Product 3 |
+----+-----------+--------------+
Really, ANY sort after the initial sort order.
You can do this by enumerating the results for each vendor and then sorting on that.
select s.*
from (select s.*,
(#rn := if(#v = vendor, #rn + 1,
if(#v := vendor, 1, 1)
)
) as seqnum
from (<your query here>) s cross join
(select #v := '', #rn := 0) params
order by vendor
) s
order by (seqnum = 1) desc,
price asc; -- or whatever you want to sort by