UNION MySQL, Check if its bold - mysql

Hello guys i have that SQL:
SELECT p.* FROM products p WHERE required_product_id IS NULL
UNION ALL
SELECT p.* FROM products p, orders o WHERE p.required_product_id = o.product_id
AND o.user_id = 1
UNION DISTINCT
SELECT p.`*` FROM products p, orders o WHERE p.id NOT IN (SELECT product_id FROM orders WHERE product_id = p.id AND o.user_id = 1)
AND p.max_buys = 1;
This query first checking if item is purchased and show next item! i want to check if user is purchased that product to return only that product that user is not bought it
table structure = Products: http://prntscr.com/k6ogp4 ,Orders: http://prntscr.com/k6ogrz
max_buys colum on products (if it 1 it can buy it once , if its 0 it can be buyed many times)

In your case I prefer to have a flexible query to manage requirements and also I think that UNION is not required in this case [if your description is complete].
SELECT w.* from (
SELECT
(SELECT count(o.product_id) FROM orders o WHERE o.product_id = p.id AND o.user_id = 1) bought_count,
(SELECT count(q.product_id) FROM orders q WHERE q.product_id = p.required_product_id AND q.user_id = 1) order_depend,
p.*
FROM products p ) w
where
(order_depend>0 or required_product_id is null) and -- unlock order depended products
(max_buys=0 or -- can buy more than once
bought_count=0) -- or not bought yet
order by
order_depend desc, -- dependent products to ordered products in first level
bought_count asc, -- not bought products in second level
recommended desc -- recommended products in third level
You can also manage any other order according to your requirement.

Related

Find customers that never placed an order with an employee

We have the following details from the output of a query a supplier id, a category name, and product count,
so 3 columns. Each supplier holds a certain category of products, and for each
category, the third column lists the number of products in that particular category.
How to write a query using this table which returns -
supplier if, category name, prodcount*100/totalnumberofproducts
Basically it should list the % of product in that category
The initial query that give the product count for each category is:
SELECT s.SupplierID, s.CompanyName AS Supplier, cat.CategoryName,
COUNT(*) AS CatProductCount
FROM suppliers AS s
JOIN products AS p ON s.SupplierID = p.SupplierID
JOIN categories AS cat ON p.CategoryID = cat.CategoryID
GROUP BY s.SupplierID, s.CompanyName, cat.CategoryName;
My Thoughts:
So if the initial query is S.
We could do
select supplierId, sum(productCount) as total from S groupby supplierID
This will tell us the total number of product for each supplier.
Let this query be called S2
select S.supplierId, (S.productCount*100)/S2.total from S inner join S2 on S.supplierID=S2.supplierId
I think I have the correct idea but the exact syntax I am using will not work.
you could use these two possibilities
As joined table
SELECT s.SupplierID, s.CompanyName AS Supplier, cat.CategoryName,
COUNT(*) * 100/ total as percentage_count
FROM suppliers AS s
JOIN products AS p ON s.SupplierID = p.SupplierID
JOIN categories AS cat ON p.CategoryID = cat.CategoryID
JOIN (select supplierId, sum(productCount) as total from suppliers group by supplierID ) S1 ON S1.supplierId = S,suppliers
GROUP BY s.SupplierID, s.CompanyName, cat.CategoryName;
Or as subselct
SELECT s.SupplierID, s.CompanyName AS Supplier, cat.CategoryName,
COUNT(*) * 100 / (select sum(productCount) from suppliers S1 WHERE S1.suppliers = S.supplierID ) as percentage_count
FROM suppliers AS s
JOIN products AS p ON s.SupplierID = p.SupplierID
JOIN categories AS cat ON p.CategoryID = cat.CategoryID
GROUP BY s.SupplierID, s.CompanyName, cat.CategoryName;
you should test both to see what is faster i would guess the second

Filtering query by passing idProduct, quantity

I want to create an Order_List with different ITEMS from a table called: Products
Inside table Products there are duplicates because a product is sell in different supermarkets, with differents prices.
I want the user to enter the desired product inside List table and get the lowest price. DO NOTE that every user has a different zipcode and every product belongs to a different supermarket with a different zipcode. The idea is to get the lowest price ONLY if the item has the same customer zipcode.Also, the quantity that was inserted in List table must be validated against Stock table.
This is what i have:
http://sqlfiddle.com/#!9/f9f73a/1
This is my example:
image
This is what i tried so far:
select p.idProduct, name, price, min(price)
from product p
inner join market m
on p.idMarket = m.idMarket
inner join stock s
on p.idProduct = s.idProduct
inner join list l
on p.idProduct = l.idProduct
where p.idProduct = 14
and exists (select 1
from stock s
where p.idProduct = s.idProduct
and l.quantity <= s.quantity)
group by p.idProduct, name, price
Could you please help me to solve this mess?
select p.idProduct, p.name, p.price, min(p.price)
from product p
inner join market m
on p.idMarket = m.idMarket
inner join stock s
on p.idProduct = s.idProduct
inner join list l
on p.idProduct = l.idProduct
where p.idProduct = 14
and exists (select 1
from stock s1
where p.idProduct = s1.idProduct
and l.quantity <= s1.quantity)
and p.price = (select min(price) from product p2 where p2.idProduct = p.idProduct)
group by p.idProduct, p.name, p.price

SQL to get top 3 most ordered products for every user by quantity sold

I am working on a school project the idea of which is an eCommerce site for selling beers.
I need to get the top 3 most ordered products for every individual user that has ordered something. My database includes 4 tables: users, products, orders and order_detail. The diagram is:
I think I will have to join all 4 of the tables to get that info, but I can't figure out the correct way to do it. Here is what I have generated:
SELECT u.username, p.`id` AS productId, p.`name`, od.`quantity` AS quantity
FROM `order_detail` AS od
INNER JOIN `products` AS p
INNER JOIN `users` AS u
ON od.`product_id` = p.`id`
GROUP BY od.`order_id`, p.name
ORDER BY od.`quantity` DESC, p.`name` ASC
The database script: https://pastebin.com/BvQLGqur
In order to limit the rows returned to show just the top 3 products ordered for each user, you'll need to use a sub-query with a limit clause on the order_detail.
Other than that, it just a simple join between the 4 tables.
SELECT
a.`user_name`,
d.`id` as `product_id`,
d.`name` as `product_name`,
SUM(c1.`quantity`) as `total_quantity`,
d.`price` as `product_price`,
d.`price` * SUM(c1.`quantity`) as `total_spent`
FROM `users` a
JOIN `orders` b
ON b.`user_id` = a.`id`
JOIN (SELECT c.`order_id`, c.`product_id`, SUM(c.`quantity`) as `num_ordered`
FROM `order_detail` c
ORDER BY `num_ordered` DESC
LIMIT 3) as c1
ON c1.`order_id` = b.`id`
JOIN `products` d
ON d.`id` = c1.`product_id`
GROUP BY a.`id`,d.`product_id`
ORDER BY a.`user_name`,`total_quantity` DESC, d.`name`;

Struggling with MySQL NOT EXISTS

I am trying to query our database to pull out customer data. The crucial parts are:
Pull out all customers/orders that haven't bought product_a.
This will list out customers/ orders who have purchased, product_b, product_c and product_d.
But it needs to make sure that the customer hasn't EVER purchased product_a. I need them excluded.
Is this the right way to go about the NOT EXISTS? I still feel like it's including some records that bought product_a.
SELECT
*
FROM
orders
JOIN customers AS cus ON orders.CustomerNumber = cus.CustomerNumber
WHERE
product != 'product_a'
OR (
HomeTelephone = ''
AND MobileTelephone != ''
)
AND NOT EXISTS (
SELECT
OrderNumber
FROM
orders AS o
JOIN customers AS c ON o.CustomerNumber = c.CustomerNumber
WHERE
c.EmailAddress = cus.EmailAddress
AND Product = 'product_a'
AND completed = 1
)
ORDER BY
orderdate
Without the NOT EXISTS statement, a customer record could be included even if they have bought product_a separately right?
Your Not Exists is a little off and where product != 'product_a' is redundant.
SELECT
*
FROM
orders AS o1
JOIN customers AS cus ON o1.CustomerNumber = cus.CustomerNumber
WHERE
cus.HomeTelephone = ''
AND cus.MobileTelephone != ''
AND NOT EXISTS (
SELECT
1
FROM
orders o2
WHERE
o2.CustomerNumber = cus.CustomerNumber
AND Product = 'product_a'
AND completed = 1
)
ORDER BY
o1.orderdate
This will give you the customers with their orders. Based on your description though, if you were wanting just the customer information, you could exclude the join to orders in the first part of your query, and use the Not Exist to determine if that customer purchased product_a or not.
SELECT
*
FROM
customers cus
WHERE
HomeTelephone = ''
AND MobileTelephone != ''
AND NOT EXISTS (
SELECT
1
FROM
orders o
WHERE
o.CustomerNumber = cus.CustomerNumber
AND Product = 'product_a'
AND completed = 1
)
SELECT c.*
FROM customers c
LEFT
JOIN orders o
ON o.CustomerNumber = c.CustomerNumber
AND o.product = 'product_a'
WHERE o.CustomerNumber IS NULL

Select from 3 tables with two order by before two group by

I try to get a list of products with each newest and lowest offer price
Table product:
id | name
Table offer:
id | product_id | price | created | dealer_id
Table invalids:
id | offer_id | status
I have tried:
SELECT * FROM product INNER JOIN
(
SELECT offer.product_id , offer.price
FROM offer
LEFT JOIN invalids
ON offer.id = invalids.offer_id
WHERE invalids.id IS NULL
GROUP BY offer.dealer_id
ORDER BY offer.created DESC
) o
ON o.product_id = product.id
ORDER BY product.name
I have tried an sqlfiddle http://sqlfiddle.com/#!9/32658/3 with this offer values:
(`id`, `price`, `dealer_id`, `product_id`, `created`)
(1,12.60,1,1,'2015-05-17 08:44:45'),
(2,13.00,1,1,'2015-08-17 08:44:45'),
(3,20.00,1,1,'2015-08-17 08:45:30'),
(4,10.00,1,1,'2015-08-17 08:45:46'),
(5,4.00,2,1,'2015-05-17 08:44:11'),
(6,11.00,2,1,'2015-08-17 08:44:46'),
(7,5.00,2,1,'2015-08-17 08:45:31'),
(9,110.00,2,2,'2015-08-17 08:46:58'),
(10,11.00,2,2,'2015-08-17 08:47:12');
Expected value for product ID 1 is offer ID 7 with price 5.
These steps I think I must realize:
Order offers by created and group by dealer_id to get newest entries
Take result from step 1 and order it by price to get smallest price.
Make this for all products
Maybe I must use a second SELECT FROM offer with GROUP BY and ORDER BY but how do I get I the product_id from the first (outer) select?
Well I would start by getting the latest date for each product offer like this:
SELECT product_id, MAX(created) AS latestOffer
FROM offer
GROUP BY product_id;
Once you have that, you can join it to the original table to get that offer:
SELECT o.*
FROM offer o
JOIN(
SELECT product_id, MAX(created) AS latestOffer
FROM offer
GROUP BY product_id) tmp ON tmp.product_id = o.product_id AND tmp.latestOffer = o.created;
Here is an SQL Fiddle example.
This query should help you:
SELECT *
FROM product
JOIN (
SELECT product_id, min(price) as minPrice, max(created) as newestOffer
FROM offer
WHERE id NOT IN (SELECT offer_id FROM invalids)
GROUP BY 1
) as b
ON product.id = b.product_id
A shot in the dark based on what I understand you to be after...
lots of nested subqueries.. keep thinking there's got to be a better way...
SELECT OO.ID, OO.Price, OO.Dealer_Id, OO.Product_ID, OO.created, P.name
FROM Offer OO
INNER JOIN (
SELECT Min(Price) as MinP
FROM offer O
INNER JOIN (
SELECT max(OI.created) as LatestOffer, OI.Dealer_ID, OI.Product_ID
FROM Offer OI
LEFT JOIN invalids I
on OI.Id = I.offer_Id
WHERE I.ID is null
GROUP BY OI.Dealer_Id, OI.Product_Id
) B
on O.Dealer_Id = B.Dealer_Id
and O.Product_Id = B.Product_Id
and O.Created = B.LatestOffer
) Z
on OO.Price = Z.MinP
INNER JOIN product P
on P.ID = OO.Product_ID
SQL FIDDLE