Get correct details when using MAX() function in mySQL - mysql

So I have two mySQL tables: products and prices. In products I have the informations about the product (id, name, type, date,...) and prices include informations for the prices for a products. i.E. product USB with ID CF003X from table products is available in tableprices with sellers (A, B, C and prices 18.00, 12.00, 13.50).
Now, when I want to select the highest price for a date, groupped by product IDs, the query returns the highest prices, but doesnt show correctly from which seller.
I also want to get results where i.E. seller 'Asus' had the highest price1
SQL Fiddle

This is a typical example where subqueries can be used: create a subquery that returns the highest price for product in a certain data range, then join this back to the prices table and get the supplier(s) who supply at that price. The date range, however, should probably be in the prices table, not in the products one. Prices change, products not really (they can be flagged as not to be listed). You should also consider having a product and a pricing id in the pricing table.
However, I'm going along with the fields you supplied within the sqlfiddle example.
select prod.id, p.seller, p.price1, p.price2
from prices p
inner join (select id, max(price1) as maxprice from prices group by id) mp on p.id=mp.id and p.price1=mp.maxprice
inner join products prod on p.id=prod.id
where prod.date='...'
You can extend the above query to show a specific vendor only by adding that vendor to the where criteria.

Related

Retrieve columns from three tables

I want to use columns from three different tables and use them to calculate how much each customer has ever spent.
tblCustomer(CustomerID)
tblOrder(CustomerID, ProductID, Amount)
tblProduct(ProductID, Price)
So I want to filter out the orders made by a customer, check what product they ordered and what amount of it, check the price and multiply it with the amount they ordered and do that with every customer
expected result:
CustomerID | TotalSpent
1|20
2|130
This depends on the relationship between the tables. The below assumes there is only one price per product in the price table. The customer table is excluded as it is unnecessary but could be joined again using the customerID
SELECT tblOrder.CustomerID,
SUM(tblOrder.Amount*tblProduct.Price) AS 'TotalSpent'
FROM tblOrder JOIN tblProduct ON tblProduct.ProductID = tblOrder.ProductID
GROUP BY tblOrder.CustomerID

How to get the GROUP BY where the lowest value is the one shown

So I have these 3 value that has the same product_id and I'm grouping them by product_id in my query but I want the one that's returned to be the one with the lowest price. So, in this case, it would display the Impact Diet Whey (Amostra) - 60g - Natural Baunilha instead of Alcool Gel
My DB:
My current query:
SELECT * FROM products_data.retailers GROUP BY product_id
I tried ORDER_BY price but still displays the Alcohol Gel first and only orders the full result by the price
I'm guessing that you GROUP BY a few product_id and you want to know which have the lowest price. One way you can achieve that is by making a sub-query with MIN(price) grouped by product_id then joined with the table again to get each product_id that have the lowest price. Consider this query example:
SELECT B.* FROM
(SELECT product_id,MIN(price) min_price FROM products GROUP BY product_id) A
JOIN products B
ON A.product_id=B.product_id
AND A.min_price=B.price;
Since this join is on product_id and price, it means that if a product_id have more than 1 with lowest price, it will return everything correspond to the lowest price and product_id. You can refer to this fiddle example : https://www.db-fiddle.com/f/7pHTqTDYpbEEwViy71P5F4/0
It makes no sense to SELECT * when grouping by product_id. This query is invalid and should raise an error, because it requests the DBMS to show the currency, the shipping, the rating ... for a product, but there ain't just one currency, one shipping, one rating for a product in the table (or at least this isn't guaranteed to be the case).
If MySQL doesn't raise an exception, then you are using an old version without sql_mode = 'ONLY_FULL_GROUP_BY'. Use this setting until you understand what GROUP BY does.
To get the row with the lowest price, order by price and limit to one row:
SELECT *
FROM products_data.retailers
ORDER BY price
LIMIT 1;
On a side note: You may want to make sure you only compare prices of the same currency.

MySQL: check all values in a subset are in another table and output corresponding IDs

I have 3 tables:
Store(sID, name, address, mID)
Sells(sID, pID)
Product(pID, name, manufacturer, price)
I need to find which stores stock every product from a given manufacturer. For example: to search Unilever, I'd expect to return only stores which stock ALL Unilever products listed in Product, not just some of them.
I've tried lots of different queries with most being completely off the mark.
Am I right in thinking I need to create a subset of all the products made by Unilever, then somehow go through Sells and check that the list of pIDs for each sID contain all of those in the initial subset? I can then join the result with Store to get the store details.
If that's the correct logic, where would one begin?
This creates a subset of all the unilever products:
SELECT pID FROM Product WHERE manufacturer = "Unilever"
How would I then check this list against each store in Sells to find the ones that contain all the products in the list?
One possible way is to join the product table twice, once via the sells table and once directly, then use COUNT(DISTINT ...) on each joined table to check they match
SELECT st.*
FROM store st
INNER JOIN sells se ON st.sID = se.sID
INNER JOIN product pr1 ON se.pID = pr1.pID AND pr1.manufacturer = "Unilever"
INNER JOIN product pr2 ON pr2.manufacturer = "Unilever"
GROUP BY st.sID,
st.name,
st.address,
st.mID
HAVING COUNT(DISTINCT pr1.pID) = COUNT(DISTINCT pr2.pID)
how about creating a Product column in Store table so that all you have to do is search for Unilever Product in the Store table. Then apply this:
SELECT Product FROM Store WHERE Product = "Unilever"
But of course you wouldnt want the column Product in your Store table so my answer cant be correct then

Mysql double select or inner join

I have two MySql tables.
One of them stores general data about a product (name, image, description).
table name: product
table fields: id, name, desc, brand, image, status
The second one stores different variations about products (size, color, price, promotion price).
table name: product_variation
table fields: product_id, size, color, price, prom_price, status
The thing I don't realy know is how to display the products from the first table ordered by the prices from the second table, considering that in the second table there are more than one rows with the same product id, but different sizes, color and of course prices. By default the price field should be considered, but if there is a data larger then 0 in the prom_price field, than prom_price should be considered.
EDIT: the result I need is one instance of every product from the first table, with the lowest possible price from the second table (from all variations of that product in the second table)
SELECT * FROM product p
INNER JOIN product_variation pv
ON p.id = pv.product_id
ORDER BY pv.prom_price, pv.price
This will duplicate your product row for however many variants you have (and show all of these variants in the related fields as well). It orders by prom_price at first and if it's 0 (or not unique) then orders by price.
Edit: You might want to GROUP BY p.id if you want the products kept together.
This is one way of doing it, find the cheapest price on a product (price or prom_price) using a left join, and order by that price. The repeating CASE expressions would be easy to remove using common table expressions, but sadly, MySQL does not have those :-/
SELECT p.name FROM products p
JOIN product_variations pv1 ON p.id=pv1.product_id
LEFT JOIN product_variations pv2 ON pv1.product_id = pv2.product_id
AND CASE WHEN pv1.prom_price<>0 THEN pv1.prom_price ELSE pv1.price END >
CASE WHEN pv2.prom_price<>0 THEN pv2.prom_price ELSE pv2.price END
WHERE pv2.product_id IS NULL
ORDER BY CASE WHEN pv1.prom_price<>0 THEN pv1.prom_price ELSE pv1.price END;
An SQLfiddle to test with.

Calculate value from two field in third field

I'm trying to create a query, that will calculate sum of products on invoice. I have 3 tables :
Product (with product's price)
Invoice (with invoice id)
Products on invoice (with invoice id, product id and number of particular products)
So in my query I take invoice_id (from invoice), price (from product),number of products sold and invoice_id (from products on invoice) and calculate their product in fourth column. I know I should use 'Totals' but how to achieve that ?
The following added to your SELECT should do it.
[Product].[price] * [Products on invoice].[number of products on invoice] AS Total
If you include the fields and table names, I can give you a much more accurate statement.
Edit:
SELECT
invoice.invoice_id,
product.price,
products_on_invoice.amount,
product.price * products_on_invoice.amount AS Total
FROM
invoice INNER JOIN
(products_on_invoice INNER JOIN
product
ON products_on_invoice.product_id = product.product_id)
ON invoice.invoice_id = products_on_invoice.invoice_id