2015-08-16 75 views
1

社區面臨的挑戰!我有一張介紹多家商店的地圖。當用戶點擊商店時,它應該只加載相關產品。要做到這一點,我有四個表(見下文)。使用數據透視表的高級雄辯過濾

我能夠從品牌調出相關產品,如果用戶通過使用if(!is_null($gender)) $q->where($gender, '=', 1);。然而應用了性別過濾$gender我希望能夠呈現即使用戶沒有正確的產品不是過濾器

挑戰在於,一個品牌可以爲男性和女性都有產品,但放置在不同的商店(或在同一家商店)。爲了跟蹤這個,我有一個名爲brands_stores的數據透視表。

總之 - 我想補充的是像

$q->with(['products' => function ($q) use ($product_ids [GENDER(S) FROM PIVOT TABLE]){ 
    $q->whereIn('gender', [GENDER(S) FROM PIVOT TABLE]; 
} 

下面的現有查詢。

查詢

// Get stores 
    $query = Store::with(['brandsUnfiltered' => function ($q) use ($active, $gender, $product_ids){ 
     if(!is_null($active)) $q->where('active', '=', 1); // Active stores 
      if(!is_null($gender)) $q->where($gender, '=', 1); // Gender 
      $q->with(['products' => function ($q) use ($product_ids){ 
       $q->whereIn('id', $product_ids); 
       $q->orderBy('brand', 'asc')->orderBy('gender', 'desc')->orderBy('category', 'asc')->orderBy('sub_category', 'asc'); 
       $q->groupBy('brand', 'name'); 
       $q->select('id AS product_id', 'name', 'brand', 'price', 'img_link'); 
       }]); 
      }]) 
      ->whereIn('id', $store_ids) 
      ->select('id', 'name', 'lat', 'lng', 'formatted_address AS address', 'street_number', 'route', 'open_monday', 'open_saturday', 'open_sunday', 'close_monday', 'close_saturday', 'close_sunday', 'formatted_phone_number AS phone'); 

     $stores = $query->get(); 
    } 

Store模式

class Store extends Eloquent { 

    public function brandsUnfiltered(){ 
     return $this->belongsToMany('\App\Brand', 'brands_stores', 'store_id', 'brand_id') 
      ->withPivot('active', 'brand_store', 'women', 'men'); 
    } 
} 

商店表

  • ID
  • ...

品牌表

  • ID
  • ...

Brands_stores表

  • ID
  • STORE_ID
  • brand_id
  • 女性[布爾]
  • 男人[布爾]
  • ...

Products表

  • ID
  • 品牌
  • 性別
  • ...

=====編輯=====

產品掛鉤於BRANDS與之連接的STORES

每個產品都有一個品牌欄目。該品牌列與品牌模型中的名稱列相同。 Brands_Stores TABLE將哪些品牌以及該商店的哪些商品通過該品牌鏈接起來。邏輯流程:

  • 該店是否攜帶相關品牌?
  • 如果它攜帶相關品牌 - (男性或女性或兩者),其產品
  • 獲取有關產品

SQL查詢

select `brand` from `products` where `name` like '%louboutin%' or `brand` like '%louboutin%' group by `brand`, `name` 

select * from `products` where (`brand` in ('Christian Louboutin')) group by `brand`, `name` 

select `id` from `brands` where `name` in ('Christian Louboutin') 

select `store_id` from `brands_stores` where (`active` = '1' and `brand_id` in ('278')) 

select `id`, `name`, `formatted_phone_number` as `phone` from `stores` where `id` in ('561', '562', '563', '2182') 

select `brands`.*, `brands_stores`.`store_id` as `pivot_store_id`, `brands_stores`.`brand_id` as `pivot_brand_id`, `brands_stores`.`active` as `pivot_active`, `brands_stores`.`brand_store` as `pivot_brand_store`, `brands_stores`.`women` as `pivot_women`, `brands_stores`.`men` as `pivot_men`, `brands_stores`.`children` as `pivot_children` from `brands` inner join `brands_stores` on `brands`.`id` = `brands_stores`.`brand_id` where `brands_stores`.`store_id` in ('562', '2182') and `active` = '1' 

select `id` as `product_id`, `name`, `brand`, `price`, `img_link` from `products` where `products`.`brand` in ('Christian Louboutin') and `id` in ('6800', '7538', '7612', '7582', '8095', '7104', '8053', '7995', '7115', '7485', '7997', '7866', '7622', '6820', '7682', '8000', '8055', '6838', '7589', '7046', '7232', '6810', '7609', '7429', '7597', '7557', '7593', '7458', '7481', '7572', '7620', '7238', '7537', '6843', '7619', '7598', '8036', '7284', '6956', '7993', '6863', '8039', '7614', '7493', '7315', '7318', '6841', '7509', '7198', '5813', '8203', '7623', '7441', '8096', '7957', '6522', '6850', '8056', '7821', '6753', '6632', '7569', '7994', '7784', '9388', '9431', '9440', '9392', '6348', '6373', '5989', '7339', '7329', '7340', '7502', '7544', '7586', '7636', '7252', '7179', '7564', '6771', '6461', '6554', '6563', '6442', '5756', '5770', '7439', '7373', '7313', '7349', '7293', '7595', '7323', '7565', '8073', '9363', '9411', '5910', '5899', '6136', '5828', '6577', '6601', '7551', '7392', '7543', '7872', '8076', '7517', '7849', '7531', '7602', '7410', '6836', '7401', '6851', '8034') group by `brand`, `name` order by `brand` asc, `gender` desc, `category` asc, `sub_category` asc 
+0

一)如何做你的'product'表中的數據模型適合?我不能看到連接它的'product_id' b)請提供MySQL查詢,而不是它的創建語法。 – Benvorth

+0

@Benvorth請參閱更新問題 –

回答

1

如果用戶選擇存儲你想要的「只加載相關產品」。

讓我們通過選擇一家商店開始:

SELECT stores.id 
FROM stores 
WHERE stores.name = 'selectedStoreName'; 

現在我們在這家商店獲取可用的品牌:

SELECT stores.id, brands_store.brand_id 
FROM stores 
JOIN brands_store ON stores.id = brands_store.store_id 
WHERE stores.name = 'selectedStoreName'; 

品牌名稱不是品牌標識符更好:

SELECT stores.id, brands_store.brand_id, brands.name 
FROM stores 
JOIN brands_store ON stores.id = brands_store.store_id 
JOIN brands ON brands_store.brand_id = brands.id 
WHERE stores.name = 'selectedStoreName';  

最後,我們從可用品牌中提取所有產品:

SELECT stores.id, brands_store.brand_id, brands.name, products.name, products.gender 
FROM stores 
JOIN brands_store ON stores.id = brands_store.store_id 
JOIN brands ON brands_store.brand_id = brands.id 
JOIN products ON brands.name = products.brand_name 
WHERE stores.name = 'selectedStoreName'; 

的方式很乾淨的數據架構...

+0

謝謝。面臨的挑戰是我說我想一次在多家商店做到這一點。換句話說,預加載數據,因此當用戶點擊商店時,不需要查詢服務器。你知道如何使用pivot_table數據作爲'變量'的方法。例如。如果女裝的brands_stores列爲1(真),而男裝爲0(假),那麼爲該商店選擇的產品應該只是女裝產品。 –

+0

如果您希望從所有商店預先加載僅限女性的產品,只需用'products.gender ='women''替換最後一個查詢中的'stores.name'部分 – Benvorth

+0

早該謝謝@Benvorth。棘手的部分是所有商店的「性別」信息都不一樣。它來自數據透視表(brands_store)。我針對分別匹配每個商店的商店提出了3個查詢(一個用於男性和女性,一個用於男性,另一個用於女性)的殘酷解決方法。對優雅不感到滿意,但完成了工作。 –

相關問題