Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Всем доброго времени суток.
Необходимо сделать в одном запросе выборку из двух таблиц.
1) есть таблица товара Products
id | category_id | name | price
в ней есть колонка цена - price (что логично общее для всех продуктов)
2) есть таблица атрибутов Attributes
id | category_id | name
в ней хранятся названия уникальных атрибуты для товаров
как вариант:
аккумуляторы - емкость
жесткий диск - объем
3) есть таблица принадлежности атрибута продукту Product_Attributes
id | product_id | attribute_id | value
как понятно из названия тут соответствия продукта атрибуту
полюс еще колонка value - тут собственно сами данные атрибута
Собственно проблема в том, что необходимо сделать выборку из двух таблиц:
по price (от и до) и по value (от и до) скажем для "жесткого диска"
В Products прописана связь одинКоМногим
public function productattributes() {
return $this->hasMany('ProductAttribute');
}
В Product_Attributes прописана связь многиеКОдному
public function product() {
return $this->belongsTo('Product');
}
Подскажите как правильно организовать запрос.
Пробовал в начале так:
$products = Product::orderBy('updated_at', 'DESC')
->where('category_id', '=', $id)
->whereBetween('price', [$priceMin, $priceMax])
->with('productattributes')
->whereBetween('value', [$sizeMin, $sizeMax])
->get();
Но (как всем понятно) это не сработало.
Я понимаю, что что-то не понимаю, в что понять не могу. (((((
За ранее спасибо всем.
Не в сети
По-моему, здесь проблема не в запросе, а скорее в неправильно спроектированных таблицах.
Не в сети
По-моему, здесь проблема не в запросе, а скорее в неправильно спроектированных таблицах.
Возможно Вы правы. Как Вы считаете, что нужно именно сделать?
И как все же реализовать запрос?
Спасибо )
Не в сети
По-моему, здесь проблема не в запросе, а скорее в неправильно спроектированных таблицах.
По моему Вы правы. По определению Entity–attribute–value, Value должен быть отдельной таблицей.
Но всеравно, как тогда организовывать запрос-выборку?
Не в сети
Нашел решение (хотя и не самое изящное).
По поводу таблиц, думаю все же правильная структура выбрана. Скорее всего не хватает некой связующей таблицы как вешнего ключа.
Если кто поправит или подскажет - спасибо огромное.
Эта мой первый проект на laravel и грабли, думаю не избеджны )))
Не в сети
Для каждого товара атрибут только один? Т.е. если это жесткий диск, то он имеет только объем? Или атрибутов для каждого товара буде много? Объем, размер, скорость и.т.д.?
Не в сети
Для каждого товара атрибут только один? Т.е. если это жесткий диск, то он имеет только объем? Или атрибутов для каждого товара буде много? Объем, размер, скорость и.т.д.?
Ну, на самом деле атрибутов много)))
И, в зависимости от категории, будут выводится разные (как количественно, так и качественно).
Как пример - вывод всех (почти всех ))) атрибутов:
Общее представление таблиц с содержимым:
(таблица categories)
id | name
1 | Жесткие диски
2 | Аккумуляторы
(таблица protucts)
id | category_id | name | price
1 | 1 | WD | 100
2 | 1 | Sams | 200
3 | 2 | Super| 20
(таблица attributes)
id | category_id | name
1 | 1 | Объём
2 | 1 | Тип
3 | 1 | Скорость
4 | 2 | Ёмкость
5 | 2 | Тип
(таблица protuct_attributes)
id | protuct_id | attribute_id | value
1 | 1 | 1 | 1Tb
2 | 1 | 2 | sata II
3 | 1 | 3 | 7 200
4 | 2 | 1 | 2Tb
5 | 2 | 2 | sata III
6 | 2 | 3 | 10 000
7 | 3 | 4 | 2800
8 | 4 | 5 | AA
Вот, как то так))
Задача заключается в том, что бы одним запросом отсортировать и вывести данные по продукту
как по цене (таб. products) , так и скорости (таб. attributes, protuct_attributes ) (для жестких дисков, как вариант)
Но создается такое впечатление, что в laravel, средствами ORM, подобные запросы в принципе не возможны.
Тут еще не указанно одна таблица product_images - там хранятся ссылки на изображения продуктов.
Вот почему принципиально важно решить задачу именно с использованием ORM.
Буду признателен за правки и любую конструктивную критику )))))
Не в сети
Через Eloquent скорее все не получится. Через ОРМ работает.
Это запрос всех товаров со всеми атрибутами и значениями атрибутов, с названием категории с сортировкой по цене.
class MainController extends BaseController {
public function index()
{
$data=DB::table('products')
->leftJoin('categories','products.category_id','=','categories.id')
->leftJoin('atributes','atributes.category_id','=','categories.id')
->leftJoin('value','value.atribute_id','=','atributes.id')
->select('products.name as name','products.price as price','categories.name as category','atributes.name as atribute','value.value')
->orderBy('products.price')
->get();
return View::make('index',['data'=>$data]);
}
}
Во вьюшке делаешь разбор
@foreach($data as $item)
{{$item->price}}
{{$item->name}}
....
{{$item->value}}
Не в сети
Через Eloquent скорее все не получится. Через ОРМ работает.
Это запрос всех товаров со всеми атрибутами и значениями атрибутов, с названием категории с сортировкой по цене.class MainController extends BaseController { public function index() { $data=DB::table('products') ->leftJoin('categories','products.category_id','=','categories.id') ->leftJoin('atributes','atributes.category_id','=','categories.id') ->leftJoin('value','value.atribute_id','=','atributes.id') ->select('products.name as name','products.price as price','categories.name as category','atributes.name as atribute','value.value') ->orderBy('products.price') ->get(); return View::make('index',['data'=>$data]); } } Во вьюшке делаешь разбор @foreach($data as $item) {{$item->price}} {{$item->name}} .... {{$item->value}}
Спасибо ))))))
Попробую так.
Не в сети
Через Eloquent скорее все не получится. Через ОРМ работает.
Это запрос всех товаров со всеми атрибутами и значениями атрибутов, с названием категории с сортировкой по цене.class MainController extends BaseController { public function index() { $data=DB::table('products') ->leftJoin('categories','products.category_id','=','categories.id') ->leftJoin('atributes','atributes.category_id','=','categories.id') ->leftJoin('value','value.atribute_id','=','atributes.id') ->select('products.name as name','products.price as price','categories.name as category','atributes.name as atribute','value.value') ->orderBy('products.price') ->get(); return View::make('index',['data'=>$data]); } } Во вьюшке делаешь разбор @foreach($data as $item) {{$item->price}} {{$item->name}} .... {{$item->value}}
Тут есть один недостаток - не учтена обработка whereBetween для многих атрибутов
Пример выборки по цене от 1000 до 3000
$data=DB::table('products')->whereBetween('price',[1000, 3000])
->leftJoin('categories','products.category_id','=','categories.id')
->leftJoin('atributes','atributes.category_id','=','categories.id')
->leftJoin('value','value.atribute_id','=','atributes.id')
->select('products.name as name','products.price as price','categories.name as category','atributes.name as atribute','value.value')
->orderBy('products.price')
->get();
Не в сети
Пример выборки по цене от 1000 до 3000
$data=DB::table('products')->whereBetween('price',[1000, 3000]) ->leftJoin('categories','products.category_id','=','categories.id') ->leftJoin('atributes','atributes.category_id','=','categories.id') ->leftJoin('value','value.atribute_id','=','atributes.id') ->select('products.name as name','products.price as price','categories.name as category','atributes.name as atribute','value.value') ->orderBy('products.price') ->get();
Спасибо) Ну это просто, так как price находится в главной (protuct) таблице, а вот атрибуты в отдельной (product_attributs) и к одному продукту могут относиться несколько атрибутов. И отличить атрибуты можно только по product_id (как привязка к продукту) и attribute_id (как как привязка к идентификатору атрибута).
Т.е. у продукта может быть несколько атрибутов с одинаковыми value и отличатся только по id атрибута.
А значит нудно фильтровать value по соответствующему attribute_id который принадлежит protuct_id.
О как завернул))
Пока однозначного решения не нашел.
Не в сети
Страницы 1