Getting unique stores a brand - mysql

I have 3 models, Store, Item and Brand. I want to figure out in which stores a given brands items can be found.
I've been trying to create a SQL statement to achieve this, but I can't get near the right result.
Essentially, I want to give the brand ID 1, and get a list of stores that have products from this brand.
How can I do this?
Here's my 4 tables:
brand
id | name
items
id | name | brand_id
stores
id | name
stores_items
id | store_id | item_id

You just need to JOIN your tables. This will return all stores where you can find brand = 1:
SELECT DISTINCT stores.name
FROM
stores INNER JOIN stores_items
ON stores.id = stores_items.store_id
INNER JOIN items
ON stores_items.item_id = items.id
WHERE
items.brand_id = 1

Related

Mysql subquery in where clause that returns comma separated value

I'm not really good at subqueries, here's the sample tables that I have.
table customers
=====================
id | name | order_ids
1 | John | 1,2
table orders
=====================
id | name
1 | apple
2 | orange
I'm trying to get the order names using this query, but I'm only getting one result. I'm not sure if this is possible.
select o.name
from orders o
where o.id IN(
select c.order_ids
from customers c
where c.id=1
)
Your primary effort should go into fixing your design. You should not be storing several integer values in a string column. If each order belongs to a single customer, then the customer id should be stored in the orders table. If an order may belong to multiple customers at once, then you need a bridge table, with one row per customer/order tuple.
That said: for you current design, you can use find_in_set():
select o.*
from orders o
inner join customers c on find_in_set(o.id, c.order_ids)
where c.id = 1

Get the lowest price for a product from a table of product prices per store

I am making a website to compare product prices between different stores. I have created a search function where I want to display the current lowest price and this is where I am a bit stuck.
I have a table Products with the basic information and a table product_store with the prizes in different stores for different products. Below is a basic schema of the database for these tables:
+-----------+ +---------------+
| products | | product_store |
+-----------+ +---------------+
| id | | product_id |
| name | | store_id |
+-----------+ | price |
| created_at |
+---------------+
The product_store table has multiple prices for the same product_id and store_id so I can create a price history.
Now I would like to create a query to get all products and their lowest price at the moment. So, you take the price for each store with the highest created_at, and from this collection I want to get the lowest value.
This is what I have tried so far:
select products.*, prices.price
from products
left join (
SELECT p1.product_id, min(p1.price) as price, p1.created_at
FROM product_store p1
WHERE p1.created_at = (SELECT max(created_at) FROM product_store p2 WHERE p2.store_id = p1.store_id
) as prices
on prices.product_id = products.id
I search for the highest created_at per store and product and get the lowest price for these rows. However this gives some very strange results where the prices get mixed up between the products and some products that have prices don't have any in the results.
Can someone help me to create a good query for this problem?
Thanks in advance. :)
Here is one method. It aggregates the product_store table to get the maximum created date for each store. Then it joins it back to that table to get price and finally does an aggregation in the outer query:
select p.*, min(ps.price)
from products p left join
(select ps.product_id, ps.store_id, max(created_at) as maxca
from product_store ps
group by ps.product_id, ps.store_id
) pssum
on pssum.product_id = p.id left join
product_store ps
on ps.product_id = pssum.product_id and
ps.store_id = pssum.store_id and
ps.created_at = pssum.maxca
group by p.id;
Your product_store table is an example of a slowly changing dimension. If it were set up with a eff_date and end_date (effective date and end date) columns, then the query would be easier to write and probably more efficient in terms of performance.

mysql where multiple fields in

I want to extract unique minlat, minlng based on city and country then want to find all id which have this pair I mean something like
select id from spots
where (minlat,minlng) in
(select s.minlat, s.minlng from spots s, spot_cards sc
where sc.spot_id=s.id and sc.country="italy"
and
(sc.city="perugia" or sc.locality="perugia" or sc.sublocality="perugia")
);
Structure of spots table is:
+----+-----------+-----------+
| id | minlat | minlng |
+----+-----------+-----------+
I created spot_cards table structure as
+---------+-------------+-------------+---------+--------+
| spot_id | sublocality | locality | country | city |
+---------+-------------+-------------+---------+--------+
by executing below query
insert into spot_cards(spot_id)
select id from spots
group by minlat,minlng
order by id
Any help is appreciated.
I think you need something like this:
Join the spots table to get all the records you want, then join again on the spots table to get the coordinates. Do a DISTINCT to get rid of any possible duplicates.
SELECT DISTINCT s2.id from spots s
INNER JOIN spot_cards sc
ON sc.spot_id=s.id
INNER JOIN spots s2
ON s.minlat = s2.minlat AND s.minlng = s2.minlng
WHERE sc.country="italy"
AND (sc.city="perugia" or sc.locality="perugia" or sc.sublocality="perugia")

many to many to many mysql query

I'm trying to create a database that is structured so that I can do ONE query and get all the data I need.
this is how I have it structured now:
Products Subcategory Category
------------- ------------- -------------
| id | name | | id | name | | id | name |
It makes sense to me to create two relational tables that ties the product to the subcategory, and the subcategory to the category (making it hierarchical):
prod_sub_relation sub_cat_relation
---------------------------- ---------------------------
| id | prod_id | subcat_id | | id | subcat_id | cat_id |
So the product can be in MULTIPLE subcategories, and the subcategory tells us what category the product is in.
With this structure, if I wanted to find all the products with a category_id, I'd have to query the sub_cat_relation table, then take that array and make another query for the prod_sub_relation table (and that's just messy).
My goal is to find all products, or all categories, or all subcategories with ONE id (whether it's product_id, category_id, or subcategory_id)
Is this possible? or am I doing something wrong here?
As already mentioned by #har07 you could use a simple JOIN on this one.
I am not exactly sure the other details of the structure of your tables but
I will show you based on what you have provided so far:
SELECT p.ID, p.Name, c.Name as CategoryName, s.Name as SubCategoryName
FROM Products P
INNER JOIN SubCategory S
ON P.subcat_id = S.subcat_id
INNER JOIN Category C
ON S.cat_id = C.cat_id
You could then use a WHERE clause to specify which product you want to display along with its category and subcategory
SELECT P.ID, P.Name, C.Name as CategoryName, S.Name as SubCategoryName
FROM Products P
INNER JOIN SubCategory S
ON P.subcat_id = S.subcat_id
INNER JOIN Category C
ON S.cat_id = C.cat_id
WHERE P.ID = valuehereforyourID
To get the Products and SubCategory for a given category ID you just change the WHERE clause, like:
WHERE C.cat_id = ValueForCategoryIDhere
To get the Products and Category for a given Subcategory ID you just change the WHERE clause, like:
WHERE S.subcat_id = ValueForSubCategoryIDhere
Put each products' categories in an array, serialize the array, and store that in the DB...

mysql joining two same columns

I know title is a bit confusing but i dont know how to name it better.
I have tables like that:
products:
product_id | product_name | product_category1 | product_category2
categories
category_id | category_name
I want to select record which looks like that:
product_id | product_name | category_name | subcategory_name (where category is category1 and subcategory is category2)
So what i need is to join 2 columns where each column is the "category_name" column but category_name has to have id saved in product_category1 and subcategory_name has to have id saved in product_category2
I tried a lot of things, but i am really stuck. I cant even paste my concept because, currently, i dont have one.
You just need to join products and categories twice, using different aliases for the categories table in the two joins. Something like:
SELECT prd.product_id, prd.product_name,cat.category_name,subcat.category_name
FROM products AS prd
JOIN categories AS cat ON cat.category_id = prd.product_category1
JOIN categories AS subcat ON subcat.category_id = prd.product_category2