2017-08-05 65 views
0

我有這樣的表格。如何獲得具有產品的嵌套類別 - 在單個查詢中?

Categories (id[PK], name, parentid); 
Product(prid[PK], product_name, product_price); 
ProductCategories(id[PK], prid[FK], catid[FK]); 

一個產品屬於多個類別。

我有一個場景,我將從用戶那裏獲得一個catid,並且必須獲得屬於該類別的產品。同時,我必須得到該類別的子類別(如果有的話)並獲得子類別的產品。 獲取類別及其子類別是一件容易的事情 - 通過自我連接。

但我必須檢查那些產品是否帶有標籤。 (意思是如果沒有在該類別/子類別下標記的產品,則忽略該類別)

例如,

Automobile (0 products) 
    Two Wheelers (0 products) 
     Mopeds (2 products) 
     Bikes (5 products) 
     Sport Bikes (0 products) 

    Four Wheelers (0 products) 
     Convertible (0 products) 
     SUV (4 products) 
     TUV (2 products) 

    Tyres (0 products) 

所以我想要的結果像(這些類別/子類別沒有產品,我必須刪除這些)。

Automobile 
    Two Wheelers 
     Mopeds 
     Bikes 
    Four Wheelers 
     SUV 
     TUV 

我正在做這件事,通過循環的類別。我可以在單個查詢中執行此操作嗎?

一些代碼:

$rows = (new \yii\db\Query()) 
    ->select(["COUNT(*) AS prodcount",'c1.parentid', "GROUP_CONCAT(c1.id, ':', c1.name) as catid"]) 
    ->from('category c1') 
    ->join('inner join','category c2','c1.id=c2.id') 
    ->where(['not in','c1.parentid','0']) 
    ->andWhere(['!=','c1.parentid',1]) 
    ->andWhere(array('c1.status'=>1)) 
    ->andWhere(array('c2.status'=>1)) 
    ->groupBy('c1.parentid') 
    ->orderBy('prodcount DESC') 
    ->all(); 

$result=array(); 

foreach ($rows as $r) 
{  
    $cats= explode(":",$r['catid']); 

    if($this->hasProducts($cats[0])) 
    { 
     if($r['parentid']!=1) 
     {     
       $pnm= \backend\models\Category::find()->select('name')->where(['id'=>$r['parentid']])->one();          
       $result['parent']=$r['parentid'].":".$pnm['name']; 
     } 
     else{     
       $result['parent']=$r['parentid'].":".'Main'; 
     } 

     $result['catid']=$r['catid']; 
     $this->cat[$result['parent']]=$result['catid']; 
    } 
} 

在這裏,我檢查類別都有至少一個產品或不?

public function hasProducts($catid) 
{ 
    $hasProducts=false; 
    $allCats= array(); 
    $allCats = $this->getAllChildren($catid); 

    if($allCats!== NULL && !empty($allCats) && sizeOf($allCats)>0) 
    { 
     $cats = implode(",",$allCats); 
     $prodcatquery = (new \yii\db\Query()) 
         ->from('product_categories pc') 
         ->where("pc.catid in ($cats)"); 
     $products= $prodcatquery->all(); 

     if (sizeOf($products)>0) 
     { 
      $hasProducts=true; 
     } 
    } 

    return $hasProducts; 
} 

獲得該類別

public function getAllChildren($catid) 
{ 
    $cats=$catid; 
    $allcats=array(); 
    $currentcats=array(); 
    array_push($allcats, $catid); 
    $intialquery = (new \yii\db\Query()) 
        ->select(['id']) 
        ->from('category') 
        ->where("parentid in ($cats)"); 
    $catidreturned = $intialquery->all();    

    $i=0;   
    while(sizeOf($catidreturned) > 0 && $i <=3) 
    { 

     foreach ($catidreturned as $categoryid) 
     { 
      array_push($allcats,$categoryid['id']); 
      array_push($currentcats,$categoryid['id']); 
     } 
     $cats= implode(',', $currentcats); 
     $intialquery1 = (new \yii\db\Query()) 
        ->select(['id']) 
        ->from('category') 
        ->where("parentid in ($cats)"); 
     $catidreturned = $intialquery1->all(); 
     $currentcats=array();  
     $i++; 
    } 

    return $allcats; 
} 

問題的所有子類別:我通過遍歷類別做這件事情。我可以在單個查詢中執行此操作嗎?

+0

添加'category'模型。什麼是序列?如果這個'category-> productCategory-> product'則表錯誤的表結構。什麼是子類別?產品或產品類別?對我不明確。 –

+0

@InsaneSkull:產品可能屬於兩個或多個類別,所以我有一個主表來顯示關係(即'ProductCategories''')。 – kishor10d

回答

0

選擇產品類別中,類別= 1個或子類別中(選擇 - 全部產品的子類別,其中ID = 1)

修改這取決於你是什麼表看起來像

0
SELECT * 
FROM (
    SELECT 
     CASE 
     WHEN c2_id IS NULL THEN 1 
     WHEN c3_id IS NULL THEN 2 
     ELSE 3 
     END AS level, 
     CASE 
      WHEN c2_id IS NULL THEN c1_id 
      WHEN c3_id IS NULL THEN c2_id 
      ELSE c3_id 
     END AS id, 
     CASE 
     WHEN c2_id IS NULL THEN c1_name 
     WHEN c3_id IS NULL THEN c2_name 
     ELSE c3_name 
     END AS name, 
     CASE 
      WHEN c2_id IS NULL THEN c1_own_products_count 
      WHEN c3_id IS NULL THEN c2_own_products_count 
      ELSE c3_own_products_count 
     END AS own_products_count, 
     CASE 
      WHEN c2_id IS NULL THEN c1_nested_products_count 
      WHEN c3_id IS NULL THEN c2_nested_products_count 
      ELSE c3_nested_products_count 
     END AS nested_products_count 
    FROM (
     SELECT 
     -- Level 1 
     c1.id AS c1_id, 
     c1.name AS c1_name, 
     COUNT(DISTINCT c1p.id) AS c1_own_products_count, 
     COUNT(DISTINCT c1p.id)+ 
     COUNT(DISTINCT c2p.id)+ 
     COUNT(DISTINCT c3p.id) AS c1_nested_products_count, 
     -- Level 2 
     c2.id AS c2_id, 
     c2.name AS c2_name, 
     COUNT(DISTINCT c2p.id) AS c2_own_products_count, 
     COUNT(DISTINCT c2p.id)+ 
     COUNT(DISTINCT c3p.id) AS c2_nested_products_count, 
     -- Level 3 
     c3.id AS c3_id, 
     c3.name AS c3_name, 
     COUNT(DISTINCT c3p.id) AS c3_own_products_count, 
     COUNT(DISTINCT c3p.id) AS c3_nested_products_count 
     FROM Categories c1 
     LEFT JOIN Categories c2 ON(c2.parentid = c1.id) 
     LEFT JOIN Categories c3 ON(c3.parentid = c2.id) 
     LEFT JOIN ProductCategories c1p ON(c1p.catid=c1.id) 
     LEFT JOIN ProductCategories c2p ON(c2p.catid=c2.id) 
     LEFT JOIN ProductCategories c3p ON(c3p.catid=c3.id) 
     GROUP BY c1.id, c2.id, c3.id 
     WITH ROLLUP -- This will generate subtotals for level 1 and 2 
) AS tree 
    WHERE c1_id IS NOT NULL -- Skip the row with total product count. 
) AS list 
WHERE nested_products_count = 0 -- Skip categories with no nested products 
+0

謝謝。但是當我的深度達到3級時,這個解決方案就可以工作。就我而言,我不知道深度有多深。它也可能超過6-8。 – kishor10d

+0

@ kishor10d您的數據庫是否支持「WITH RECURSIVE」SQL語句? –

+0

@ kishor10d您還可以修改我的查詢以獲得儘可能多的級別。 –

相關問題