How can I retrieve similar Orders having exact matching itemSku In Mysql? - php

ID OrderNumber
1 123456
2 234567
3 345678
4 456789
***PurchasedProductsTable***
OrderId itemSku
1 1001
1 1002
2 1001
3 1001
3 1002
4 1001
In the above table I pass itemSku value and the query should retrieve only that itemSku containing similar orders (in purchasedProducts table).
Here if I pass 1001, it matches the itemSKu (1001) in order id 2 and 4 so order 2 and 4 are retrieved not containing other itemSku as order id 2 and 4 contains that 1001 sku only.
If I run query again with item sku 1001 and 1002 it should retrieve similar orders of 1 and 3 as order 1 and 3 contains both sku 1001 and 1002.
What I did is trying query like this but it is not working as expected it also retrieve others non matching orders.
SELECT
o.id,
o.orderNumber
FROM
OrdersTable o
INNER JOIN PurchasedProductsTable p ON p.orderId = o.id
WHERE
p.itemSku IN ('1001')
GROUP BY
p.orderId HAVING COUNT(p.itemSku) = ?
ORDER BY
o.created_at DESC

SELECT o.ID, o.OrderNumber
FROM Orders o
JOIN PurchasedProductsTable ppt ON o.ID = ppt.OrderId
CROSS JOIN ( {SKUs list as a rowset, i.e. SELECT .. UNION SELECT ..} ) sku
GROUP BY o.ID, o.OrderNumber
HAVING COUNT(DISTINCT ppt.itemSku) = SUM(ppt.itemSku = sku.sku)
AND COUNT(DISTINCT sku.sku) = SUM(ppt.itemSku = sku.sku)
or
SELECT o.ID, o.OrderNumber
FROM Orders o
JOIN PurchasedProductsTable ppt ON o.ID = ppt.OrderId
CROSS JOIN ( {SKUs list as a rowset} ) sku
GROUP BY o.ID, o.OrderNumber
HAVING GROUP_CONCAT(DISTINCT ppt.itemSku ORDER BY ppt.itemSku) = GROUP_CONCAT(DISTINCT sku.sku ORDER BY sku.sku)
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=f12e0e4d401946b5617f74da8eb311a0

Related

php - mysql join three tables and grouping

I have three tables:
products:
id name
1 juice
2 chips
3 water
orders:
id product_id order_id
1 1 special1
2 3 special1
3 2 special1
4 1 special2
5 2 special2
final_orders:
id order_id date
1 special1 25-3-2017
2 special2 25-3-2017
I want to select all products names in every order using order_id to show:
ID: Special1
Date: 25-3-2017
Products List:
juice
water
chips
ID: Special2
Date: 25-3-2017
Products List:
juice
chips
I use this:
$sql = "select * from products,orders where products.id = orders.product_id";
but it doesn't work and show me duplicated results.
thank you.
You need to join with final_orders as well:
SELECT *
FROM final_orders AS f
JOIN orders AS o ON f.order_id = o.order_id
JOIN products AS p ON p.id = o.product_id
ORDER BY f.order_id
To prevent duplication in the output, your loop that prints the output should only show the information from final_orders when it changes. See How can i list has same id data with while loop in PHP?
If you want to see one final order per record in your result set, then you will have to aggregate the products which appear in each order. One option then is the following query which aggregates order products into CSV using MySQL's GROUP_CONCAT():
SELECT t1.order_id,
t1.date,
t2.products
FROM final_orders t1
INNER JOIN
(
SELECT a.order_id, GROUP_CONCAT(b.name) AS products
FROM orders a
INNER JOIN products b
ON a.product_id = b.id
GROUP BY a.order_id
) t2
ON t1.order_id = t2.order_id
Demo here:
Rextester

selecting all row from two tables and one row from last table mysql

I want to select all row from two tables and one row from last table mysql
My table is given below,
tbl_order
order_id order_no
-------- --------
1 1000
2 1001
3 1002
tbl_assign
assign_id order_id central_status
--------- -------- --------------
1 1 1
2 2 1
3 3 1
tbl_unit_status
status_id assign_id status_status
--------- --------- -------------
1 1 Work
2 2 Cutter
3 2 Stitch
4 1 Stitch
From the above 3 table, I want the result as,
order_id order_no assign_id status_status
-------- -------- --------- -------------
3 1002 3 {null}
2 1001 2 Stitch
1 1000 1 Stitch
I have tried the below code,
SELECT * FROM tbl_order o LEFT JOIN tbl_assign a ON a.order_id = o.order_id LEFT JOIN (SELECT * FROM tbl_unit_status u ORDER BY u.status_id DESC LIMIT 1) uu ON uu.assign_id = a.assign_id WHERE a.central_status = 1 ORDER BY a.assign_id DESC
But the result comes as,
order_id order_no assign_id status_status
-------- -------- --------- -------------
3 1002 3 {null}
2 1001 2 {null}
1 1000 1 Stitch
Where am doing wrong. I have tried a lot. Please help me find the answer. Thank you.
try like this:
SELECT o.*,u2.assign_id,u2.status_status FROM tbl_order o
LEFT JOIN tbl_assign a ON a.order_id = o.order_id LEFT JOIN
(SELECT u.assign_id,max(u.status_id) as maxid FROM tbl_unit_status u group by u.assign_id)
uu ON uu.assign_id = a.assign_id
LEFT JOIN tbl_unit_status u2 on u2.status_id = uu.maxid
WHERE a.central_status = 1 ORDER BY a.assign_id DESC
Try this
SELECT * FROM tbl_order o LEFT JOIN tbl_assign a ON a.order_id = o.order_id
LEFT JOIN (SELECT * FROM tbl_unit_status u ORDER BY u.status_id DESC LIMIT 2)
uu ON uu.assign_id = a.assign_id WHERE a.central_status = 1 ORDER BY
a.assign_id DESC
With LIMIT 1 you are only comparing with the last row from tbl_unit_status which has assign_id 1.

MySQL Query to get Data of Specific Item by All Months

Okay I have a table 3 Tables (Orders, Order_details, Products)
Orders
id | order_date
1 | March-01-13
2 | March-02-13
3 | April-01-13
4 | May-01-13
5 | June-01-13
and so on.....
Order_Details
id | order_id | product_id | total_price
1 1 1 100 /*mouse*/
2 1 3 200 /*monitor*/
3 2 2 50 /*keyboar*/
4 2 3 200 /*monitor*/
and so on....
Products
id | title
1 mouse
2 keyboard
3 monitor
and so on...
And here is my SQL Query that giving unexpected output
SELECT title, SUM(total_price) as total_price, orders.order_date as date
FROM products
LEFT JOIN order_details
ON order_details.product_id=products.id
LEFT JOIN orders
ON orders.id=order_details.order_id
WHERE title='monitor' /*this is just a try, prod_id should be the one*/
GROUP BY MONTH(date)
ORDER BY total_price DESC LIMIT 10
What I want to get is the total_price of product_id in all months
Expected Output
title | total_price | date
monitor 400 March
When using a GROUP BY, all of the fields in the SELECT list need to either be aggregated, or be part of the GROUP BY. So try adding the 'title' to the group by, and adding the MONTH function to the order_date in the SELECT list as follows:
SELECT title, SUM(total_price) as total_price, MONTH(orders.order_date) as date
FROM products
LEFT JOIN order_details ON order_details.product_id=products.id
LEFT JOIN orders ON orders.id=order_details.order_id
WHERE title='monitor'
GROUP BY title, date
ORDER BY total_price DESC LIMIT 10
This will get the total_price for each product for each month.
Do you want something like this?
SELECT p.title, SUM(total_price) as total_price
FROM products p LEFT JOIN
order_details od
ON od.product_id = p.id LEFT JOIN
orders o
ON o.id = od.order_id
GROUP BY p.title
ORDER BY total_price DESC
LIMIT 10;
I don't see why your sample output would have a month in it.

Select records from two tables if atleast 4 records in second table

I have 2 tables and i want to fetch data based on below condition:
Table1 has multiple product records.
Table2 contains various Size option for products and can not have more or less than 4 rows.
Now, i want to fetch those products which do not have entry or do not have exact 4 entries.
Table Structure is as below:
Table1
id name color price instock
----------------------------------
1 rice white 1200 1
2 shoe brown 2500 1
3 belt red 5200 1
Table2
id size pid
-----------------
1 5 1
2 10 1
3 4 1
4 15 1
5 7 2
Now Query shall fetch product with ID 2 and 3 as they have records less than 4 and no record resp.
I was using below query to fetch products which have no records in Table2
SELECT p.* FROM `Table1` p LEFT JOIN `Table2` t ON p.id = t.pid WHERE
t.pid IS NULL
SELECT p.id, p.name, p.color, p.price, p.instock, count(t.*)
FROM `Table1` p
LEFT JOIN `Table2` t
ON p.id = t.pid
GROUP BY p.id, p.name, p.color, p.price, p.instock
HAVING count(t.*) < 4

Select unique product id and order by stock id desc

I'm trying to get unique product from stock...
stock table:
id - product - quantity
1 2 0
2 3 5
3 2 19
4 4 3
5 2 8
result
id - product - quantity
5 2 8
4 4 3
2 3 5
it's working with
SELECT max(id) as id,
product
FROM stock
GROUP by product
ORDER by id DESC
but I can't get last quantity of product
with this query I get:
id - product - quantity
1 2 0
2 3 5
4 4 3
I need latest quantity of the product.
You can wrap your existing query in a subquery and join that on the table itself so you can get the other columns of the same row.
SELECT a.*
FROM stock a
INNER JOIN
(
SELECT product, MAX(ID) id
FROM stock
GROUP BY product
) b ON a.product = b.product
AND a.ID = b.ID
ORDER BY a.id DESC
Assuming your definition of "latest" is max(id), I think the easiest way is:
SELECT s.id, s.product, s.quantity
FROM stock s
WHERE NOT EXISTS (SELECT 1 FROM stock s2 WHERE s2.product = s.product and s2.id > s.id);
Basically give me the stock rows where there is no row for the same product with a greater id.
You can do it with a left join of the table with itself that filters only rows without one with higher id and same product, avoiding subquery and group by, which can be very expensive on large tables:
select p1.id, p1.product, p1.quantity from stock as p1
left join test as p2 on p1.product = p2.product and p2.id> p1.id
where p2.id is null
order by p1.id desc;

Categories