Get cheapest price for a product - mysql

I have two tables: products and prices
products
id (PK)
name
prices
id (PK)
product_id (FK > products)
price
originalPrice
Each product might have multiple prices. What I want to achieve is a query that returns me all products on-sale with its cheapest price.
on-sale = price < originalPrice
if a product is not on-sale, it should not be included in the results
if a product has multiple prices that qualify for on-sale, only return the cheapest price.
The resulting table should have these columns
products.id
products.name
prices.id
prices.price
prices.originalPrice
With my attempts I'm ending up with this issue: #1055 - Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'tbl.price' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by. Please note that I cannot change the config.
MySQL version: 5.7.22
I have uploaded a SQL export with sample data here: https://www.dropbox.com/s/6ucdv6592dum6n6/stackoverflow_export.sql?dl=0

select pro.name, MIN(pri.price) from products pro
inner join price pri on pri.product_id = pro.id
where pri.price < pri.originalPrice
group by pro.name
heres a shot without any data :p may need a little tweaking

Try this:
SELECT *
FROM `products` pro
JOIN price pri on pri.productId = pro.id
WHERE pri.price < pri.originalPrice
AND pri.price =
(
SELECT min(p.price)
FROM price p
WHERE p.productId = pro.id AND p.price < p.originalPrice
)

Hope this works for you
SELECT *,MIN(price) FROM (
SELECT name, products.id,price
FROM products
INNER JOIN productItems
ON products.id = productItems.productId
WHERE price < originalPrice
ORDER BY (price-originalPrice)
) as tbl GROUP BY id;
OR
SELECT *,MIN(diff) FROM (
SELECT name, products.id,price,(price-originalPrice) as "diff"
FROM products
INNER JOIN productItems
ON products.id = productItems.productId
WHERE price < originalPrice
ORDER BY products.id,(price-originalPrice)
) as tbl GROUP BY id;

This works with that dropbox link you gave: http://sqlfiddle.com/#!9/a6306d/3
select pro.name, MIN(pri.price) from products pro
inner join price pri on pri.productId = pro.id
where pri.price < pri.originalPrice
group by pro.name

Related

Sql query using joins to find sum of quantity

Here,in billtran table the productid=1 is repeated twice
I want to find the sum(billtran.quantity) of each productid separately
select Query1:
select name,billtran.quantity from product inner join billtran on product.id=billtran.productid where product.id in(select id from product)
Per comment:
select name, SUM(billtran.quantity) from product inner join billtran on product.id=billtran.productid where product.id in(select id from product)
GROUP BY NAME
My additions in caps
Note: where product.id in(select id from product) is an entirely useless where clause and should be removed. Queries don't have to have a where clause and don't need one that says a table id should be in all the ids in that table (always true)
I would hence have written this one as:
SELECT
p.name,
SUM(b.quantity) as sumof_quantity
FROM
product p
INNER JOIN billtran b ON p.id=b.productid
GROUP BY
p.name
Very simple query. Pls check below:
select product.name,sum(billtran.quantity) from product inner join billtran on product.id=billtran.productid group by billtran.productid
First of all you have to get the sum of the quantity according to the product_id
SELECT product.name, SUM(billtran.quantity) AS value_sum
FROM billtran inner join product on product.id= billtran.product_id where product.id in(select id from product )
GROUP BY product_id;
This will be the result:
name quantity
abc 6
xyz 1
pqt 3
You can get the same result by grouping the product.name as well:
SELECT product.name, SUM(billtran.quantity) AS value_sum
FROM billtran inner join product on product.id=billtran.product_id where product.id in(select id from product)
GROUP BY product.name;

How to make a SQL query

I'm new to SQL, so I've got some troubles with creating queries.
My task is: To select a description of a product which was selling the most in 1989 with maximum discount.Product Table. Price table. What I tried to do is
Select maximum discount by subtracting list_price - min_price
select max(list_price - min_price) from PRICE
Select description
select description from product
join price on PRODUCT.product_id = PRICE.product_id
where start_date = '1989'
The problem is that I can't make it in one query
select top 1
product.product_id,
description,
max_disc = max(list_price - min_price)
from PRICE
join product on product.product_id = PRICE.product_id
where start_date = '1989'
group by product.product_id, description
order by max_disc desc
Inner Join between the two tables using product_id, and calculate ist_price - min_price AS discount
Filter out the resultset to carry prices of 1989 only, using where YEAR(start_date) = 1989
Consider the resultset as a Derived Table, and sort it using discount value in descending order. Use Limit 1 to find the product with maximum discount given in the year 1989.
For MySQL, try the following:
SELECT dt.*
FROM (
SELECT
pt.product_id,
pt.description,
pe.list_price - pe.min_price AS discount
FROM PRODUCT AS pt
JOIN PRICE AS pe ON pt.product_id = pe.product_id
WHERE YEAR(pe.start_date) = 1989
) AS dt
ORDER BY dt.discount DESC LIMIT 1
you try like below
select * from
(
select description from product
join price
on PRODUCT.product_id = PRICE.product_id
where start_date = '1989'
) t1
cross join (select max(list_price - min_price) as p from PRICE) t

How to reduce query time of the sql statement,mysql

Here is the sql(mysql):
Table product and product_sale_app
it will pass in two parameters,appkey is the attribute of table product_sale_app;category is the attribute of table product.I need get effect_date,product_id,name from table product and use the above conditions.
SELECT effect_date,
product_id,
name
FROM product
WHERE product_id IN
(SELECT product_id
FROM product_sale_app
WHERE appkey =88888
AND product_id IN
(SELECT product_id
FROM product
WHERE category =1 ) )
Instead of sub queries, JOIN the tables using product_id and then put conditions inside the WHERE clause.
Try the following:
SELECT p.effect_date,
p.product_id,
p.name
FROM product AS p
JOIN product_sale_app AS psa ON psa.product_id = p.product_id
WHERE p.category = 1 AND psa.appkey = 88888

mySQL SQL joined table then find rows with duplicates

I have two tables:
Orders
orders_ID
orderDate
Order Details
product_ID
order_ID
quantity
Products
product_ID
productName
productDescription
I want to find all the records in the Order Details of product_ID 1 and 4 (so trying to see when one order contains both of these products). So ran this code - the INNER JOIN creates a results table that contains only orders that contain product 1, 4, or 1 and 4.
Then I want to count all of the "Order Details".order_ID duplicates - these would be all of the orders that contain 1 and 4 (note- trivial database - a given order doesn't contain more than 1 of any product).
Here is my code - doesn't quite work - any thoughts?
SELECT order_ID, COUNT(*) TotalCount
FROM
(SELECT * FROM Orders o INNER JOIN "Order Details" od ON o.order_ID = od.order_ID
WHERE od.product_ID = 1 OR od.product_ID = 4)
GROUP BY order_ID
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC
Thanks- I looked through the forum but didn't see anything that helped me - been trying for some time.
I think what you want is a JOIN:
select prod1.order_id from `Order Details` prod1 JOIN `Order Details` prod4 on prod1.order_ID=prod2.order_ID where prod1.product_ID=1 and prod2.product_ID=4;

need help with tricky mySQL query

I'm asking for an awful lot here - but maybe some SQL guru can show me how to extract the data I want and save me 10+ hours of google-time(tm)?
These are my tables, with only relevant fields displayed:
**event**
id
cust_id
....
.
**art**
id
art_name
...
.
**event_art**
event_id
art_id
...
.
**price**
cust_id
art_id
price
...
Prices in the "price" DB with user ID "0" is standard price, if an entry exists with art_id and cust_id that is customer specific price for that article.
What I have is cust_id and what I have for output now is just the customer specific prices with SQL:
SELECT * FROM price WHERE cust_id='{$custID}'
But I'd like to include prices for previously ordered articles, even if they do not have a customer specific price.
So what I need is to:
1 Get all id's from table event where cust_id = custID
2 Get all distinct article ID's on those orders from table event_art
3 Output "id" and "art_name" of article from "art" and "price" from price table using custID or 0 for standard price if no entry exists.
To me this sounds like a multi-line JOIN that's a bit outside my scope of SQL knowledge. Could somebody help me out, point me to a guide that deals with similar issues or... well, something?
Thanks in advance!
SELECT art_id, price
FROM price
WHERE cust_id = $cust_id
UNION ALL
SELECT art_id, price
FROM (
SELECT DISTINCT art_id
FROM event e
JOIN event_art ea
ON ea.event_id = e.id
WHERE e.cust_id = $cust_id
AND ea.art_id NOT IN
(
SELECT art_id
FROM price
WHERE cust_id = $cust_id
)
) e
JOIN price p
ON p.cust_id = 0
AND p.art_id = e.art_id
Make sure that (cust_id, art_id) (in this order) is a PRIMARY KEY or a UNIQUE INDEX on price.
Had to make some small changes to indicate which table was used where in the SQL, but pretty much copy&paste so not bad at all :P
SELECT price.art_id, price.price
FROM price
WHERE cust_id =114
UNION ALL
SELECT e.art_id, p.price
FROM (
SELECT DISTINCT art_id
FROM event e
JOIN event_art ea ON ea.event_id = e.id
WHERE e.cust_id =114
AND ea.art_id NOT
IN (
SELECT price.art_id
FROM price
WHERE cust_id =114
)
)e
JOIN price p ON p.cust_id =0
AND p.art_id = e.art_id
SELECT DISTINCT
a.id,
a.art_name,
COALESCE(p.price, p0.price) AS price
FROM event e
INNER JOIN event_art ea ON e.id = ea.event_id
INNER JOIN art a ON ea
LEFT JOIN price p ON p.art_id = a.id AND p.cust_id = e.cust_id
LEFT JOIN price p ON p.art_id = a.id AND p.cust_id = 0