select from multiple child tables in sql - mysql

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)

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

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.

Get those items which are ordered after they have been delivered

I have two tables, namely itemOrders and itemDelivered.
itemOrders
+-------+---------+--------+
| id | orderid | itemid |
+-------+---------+--------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
| 4 | 2 | 2 |
| 5 | 3 | 1 |
| 6 | 3 | 2 |
+-------+---------+--------+
And
itemDelivered
+-------+-------------+--------+
| id | orderId | itemid |
+-------+-------------+--------+
| 1 | 2 | 2 |
| 2 | 3 | 2 |
| 3 | 2 | 1 |
+-------+-------------+--------+
From the above scenario I want all those distinct items whose max orderId in the table itemDelivered is less than max orderId in the table itemOrders.
In the above example I should get itemid 1 as the result, as it's max orderid is 2 in table itemDelivered, which is less than its max orderid in table itemOrders which is 3.
I wrote the following query but it gives me both the items, 1 and 2 as item No. 2 doesn't have orderId 1 in itemDelivered table.
SELECT DISTINCT( itemid )
FROM itemorders
WHERE orderid NOT IN (SELECT orderid
FROM itemdelivered)
You can LEFT JOIN between the two table using itemid, and GROUP BY on the itemid.
Eventually use HAVING clause to consider only those itemid values, where MAX(itemdelivered.orderid) < MAX(itemorders.orderid)
View on DB Fiddle
SELECT io.itemid
FROM itemorders AS io
LEFT JOIN itemdelivered AS id
ON id.itemid = io.itemid
GROUP BY io.itemid
HAVING MAX(id.orderid) < MAX(io.orderid)
OR MAX(id.orderid) IS NULL
Result
| itemid |
| ------ |
| 1 |
Ok, manage to write a query which gives the desired output.
SELECT io.itemid
FROM itemorders as io
LEFT JOIN itemdelivered AS id ON io.orderid = id.orderid AND io.itemid = id.itemid
WHERE id.itemid IS NULL
HAVING MAX(id.orderid) IS NULL
ORDER BY io.id

How to select bi-directional mapped rows from a table in MySQL?

I have the MySQL table called table.
| ID |item_code| item_name |
| 1 | 12345 | abc |
| 2 | 12345 | xyz |
| 3 | 11221 | abc |
| 4 | 19261 | www |
| 5 | 12345 | abc |
| 6 | 62898 | abc |
| 7 | 92648 | xxx |
| 8 | 45678 | xxx |
| 9 | 1234 | pqrs |
| 10 | 2345 | defg |
| 11 | 1234 | pqrs |
I want the query which will results the below table:
> |item_code | item_name |
> | 12345 | abc |
> | 12345 | xyz |
> | 11221 | abc |
> | 62898 | abc |
> | 92648 | xxx |
> | 45678 | xxx |
I want the result considering of:
item_code mapped to multiple item_name. Here item_code 12345 is mapped with abc and xyz. item_code 1234 is mapped to pqrs.
item_name mapped to multiple item_code. Here item_name abc is mapped with three items: 12345,11221,62898. item_name xxx is mapped to 92648 and 45678.
Here is the SQL statement I tried:
(select a.item_code,a.item_name from table a
join ( select item_code
from table
group by item_code
having count(*) > 1 ) b
on a.item_code = b.item_code)
union
(select a.item_code,a.item_name from table a
join ( select Item_name
from table
group by Item_name
having count(*) > 1 ) b
on a.Item_name = b.Item_name);
But this SQL query does not generate the bi directional mapped keys. Can someone help me generate these bi-directional mappings?
SELECT DISTINCT t.item_code, t.item_name
FROM mytable t
INNER JOIN
(SELECT item_code, COUNT(DISTINCT item_name) num FROM mytable GROUP BY item_code) code
ON (t.item_code = code.item_code)
INNER JOIN
(SELECT item_name, COUNT(DISTINCT item_code) num FROM mytable GROUP BY item_name) name
ON (t.item_name = name.item_name)
WHERE code.num > 1 OR name.num > 1
The subqueries used in the two JOIN clauses are used to attach the counts for which each item code or name is repeated. The joined result set is filtered using the WHERE clause at the outermost level to include only those DISTINCT combinations where the code and/or the name was associated with multiple values for the opposite field.

SQL Server : Many to Many

I have a many to many relationship, Orders, OrderProducts, and Products. I need a query that gives me a list of products that are NOT in ALL orders, but has been ordered.
______________________
| ORDERS |
_______________________
| OrderID | OrderDate |
| 1 | 1/2/2012 |
| 2 | 1/3/2012 |
| 3 | 1/4/2012 |
| 4 | 1/5/2012 |
| 5 | 1/6/2012 |
______________________
| ORDERPRODUCTS |
_______________________
| OrderID | PRODUCTID |
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
| 3 | 1 |
| 3 | 5 |
| 4 | 1 |
| 5 | 1 |
__________________________
| PRODUCTS |
__________________________
| PRODUCTID | PRODUCTNAME |
| 1 | Widget 1 |
| 2 | Widget 2 |
| 3 | Widget 3 |
| 4 | Widget 4 |
| 5 | Widget 5 |
| 6 | Widget 6 |
In the provided example, notice that product 1 is in all orders and product 6 is not ordered at all.
I need a query that returns Products 2, 3, 4, and 5.
Also keep in mind that while there aren't many products, there are a few hundred thousand orders in the live database.
SELECT PRODUCTID
FROM ORDERPRODUCTS
GROUP BY PRODUCTID
HAVING COUNT(DISTINCT OrderID) < (SELECT COUNT(*) FROM ORDERS )
It's Saturday night, so this is probably not the most elegant, but here's one try:
DECLARE #OrderProducts TABLE(OrderID INT, ProductID INT);
DECLARE #Products TABLE(ProductID INT, ProductName VARCHAR(32));
INSERT #Products VALUES
(1,'Widget 1'),(2,'Widget 2'),
(3,'Widget 3'),(4,'Widget 4'),
(5,'Widget 5'),(6,'Widget 6');
INSERT #OrderProducts VALUES
(1,1),(1,2),(2,1),(2,2),(2,3),
(2,4),(3,1),(3,5),(4,1),(5,1);
SELECT p.ProductID, p.ProductName
FROM #Products AS p
WHERE EXISTS -- had been ordered at least once
(
SELECT 1 FROM #OrderProducts
WHERE ProductID = p.ProductID
)
AND EXISTS -- at least one order does NOT include it
(
SELECT 1 FROM #OrderProducts AS o
WHERE NOT EXISTS
(
SELECT 1 FROM #OrderProducts AS o2
WHERE o2.OrderID = o.OrderID
AND o2.ProductID = p.ProductID
)
);
SELECT
DISTINCT
PossibleOrderProducts.PRODUCTID
FROM
(
SELECT
Orders.ORDERID,
Products.PRODUCTID
FROM
ORDERS Orders
CROSS JOIN
(
SELECT DISTINCT PRODUCTID FROM ORDERPRODUCTS
) Products
) PossibleOrderProducts
LEFT JOIN ORDERPRODUCTS ActualOrderProducts ON
ActualOrderProducts.ORDERID = PossibleOrderProducts.ORDERID
AND ActualOrderProducts.PRODUCTID = PossibleOrderProducts.PRODUCTID
WHERE
ActualOrderProducts.ORDERID IS NULL