2016-10-18 22 views
0

免責聲明我是自學的。有我的PHP閱讀論壇的基本知識。我是一個sql newb,並且幾乎不知道yii。yii分頁問題試圖使用2標準

我有一個控制器,顯示我們的網上商店的產品。我希望缺貨產品在最後幾頁上出現。

我知道我可以根據庫存數量進行排序,但是希望在每次頁面重新加載時都有貨產品更改訂單。

我的解決方案(可能是錯誤的,但有點作品)是運行兩個查詢。一種用於存貨的產品,隨機排序。一個缺貨產品也隨機訂購。然後我合併兩個結果數組。這很多工作使用下面的代碼(儘管我覺得必須有比運行兩個查詢更有效的方法)。

問題是,這會弄亂分頁。返回的每件產品都列在同一頁面上,並且更改頁面顯示相同的結果。據我所知,分頁只能同時適用於1個CDbCriteria。我已經查看了關於CPagination的yii文檔來解決這個問題,但是我沒有找到任何地方。

 $criteria=new CDbCriteria; 
     $criteria->alias = 'Product'; 
     $criteria->addCondition('(inventory_avail>0 OR inventoried=0)'); 
     $criteria->addCondition('Product.parent IS NULL'); 
     $criteria->addCondition('web=1'); 
     $criteria->addCondition('current=1'); 
     $criteria->addCondition('sell>sell_web'); 
     $criteria->order = 'RAND()'; 

     $criteria2=new CDbCriteria; 
     $criteria2->alias = 'Product'; 
     $criteria2->addCondition('(inventory_avail<1 AND inventoried=1)'); 
     $criteria2->addCondition('Product.parent IS NULL'); 
     $criteria2->addCondition('web=1'); 
     $criteria2->addCondition('current=1'); 
     $criteria2->addCondition('sell>sell_web'); 
     $criteria2->order = 'RAND()'; 

     $crit1=Product::model()->findAll($criteria); 
     $crit2=Product::model()->findAll($criteria2); 
     $models=array_merge($crit1,$crit2);     

     //I know there is something wrong here, no idea how to fix it.. 
     $count=Product::model()->count($criteria); 
     $pages=new CPagination($count); 
     //results per page 
     $pages->pageSize=30; 
     $pages->applyLimit($criteria); 

     $this->render('index', array(
     'models' => $models, 
      'pages' => $pages 
      )); 

很明顯,我在我的頭上。任何幫助將非常感激。

編輯:

我想,這既包括股票和商品缺貨的第三CDbCriteria可用於分頁(因爲它會加入相同數量的產品作爲第一的綜合結果2)。所以我嘗試添加該(標準1和criteria2保持不變):

 $criteria3=new CDbCriteria; 
     $criteria3->alias = 'Product'; 
     //$criteria3->addCondition('(inventory_avail>0 OR inventoried=0)'); 
     $criteria3->addCondition('Product.parent IS NULL'); 
     $criteria3->addCondition('web=1'); 
     $criteria3->addCondition('current=1'); 
     $criteria3->addCondition('sell>sell_web'); 
     //$criteria3->order = 'RAND()'; 

     $crit1=Product::model()->findAll($criteria); 
     $crit2=Product::model()->findAll($criteria2); 
     $models=array_merge($crit1,$crit2);     

     $count=Product::model()->count($criteria3); 
     $pages=new CPagination($count); 
     //results per page 
     $pages->pageSize=30; 
     $pages->applyLimit($criteria3); 

     $crit1=Product::model()->findAll($criteria); 
     $crit2=Product::model()->findAll($criteria2); 
     $models=array_merge($crit1,$crit2); 

     $this->render('index', array(
     'models' => $models, 
      'pages' => $pages 
      )); 

我敢肯定,我在這裏的東西超級明顯......一直在尋找一整天一事無成。

+0

使用隨機排序分頁通常沒有意義,爲什麼你會這樣做?爲什麼不只是單一的查詢與多個訂購條件(首先是可用性,然後是任何您的主要排序字段將是)? –

+0

感謝您的答覆邁克。點擊我們商店中的類別有時會產生數百種產品,我們不希望在同一頁面上顯示所有這些結果。隨機排序是這樣的:返回該類別的人可以看到新鮮的產品,而不是出現在第一頁上的相同的產品。我不確定如何按可用性進行訂購,「inventory_avail」的訂購將按數量排序,以便擁有大量庫存的產品總是首先顯示,這對我們來說並不理想。 –

回答

0

因此,您正在運行什麼是IMO自然語言查詢生成器框架的潛在缺陷之一。他們可以考慮如何在嘗試使用「開箱即用」方法構建查詢時處理SQL問題。有時您可能需要考慮使用大多數每個框架提供的原始SQL查詢功能,以便最好地解決您的問題。

因此,讓我們從基本的SQL開始,讓我建議您解決您的問題。您可以將其用於查詢生成器樣式(如果可能)或進行原始查詢。

您可以輕鬆地形成一個計算字段,表示用於排序的二進制庫存狀態。然後再按其他標準排序。

SELECT 
    field1, 
    field2, 
    /* other fields */ 
    IF(inventory_avail > 0, 1, 0) AS in_inventory 
FROM product 
WHERE /* where conditions */ 
ORDER BY 
    in_inventory DESC, /* sort items in inventory first */ 
    other_field_to_sort ASC /* other sort criteria */ 
LIMIT ?, ? /* pagination row limit and offset */ 

請注意,此方法只返回需要顯示的數據行。您遠離目前在應用程序中進行大量工作以合併記錄集等的方法。

我確實質疑使用RAND()作爲分頁目的,因爲這樣做會導致產品在用戶對頁面進行分頁時可能會出現在一個接一個頁面上,其他產品可能根本沒有顯示出來。無論是或者您需要爲您的應用程序添加一些額外的複雜性,以某種方式跟蹤每個特定用戶的整個結果集的「隨機」版本。出於這個原因,看到分頁結果顯示的順序隨機化真的很不尋常。

我知道你提到過你可能想在第一頁上向用戶展示一個隨機視圖。如果這是一個好的願望,但也許你會將該特定視圖與產品列表的更廣泛分頁視圖分離或區分開來,以免將最終用戶與看似不可預知的分頁界面混淆。

在您的ORDER BY子句中,您應始終具有足夠的排序條件,以便最終(最具體)的條件將保證您可預測的訂單結果。通常這意味着您必須包含一個自動增量主鍵字段或爲該行提供唯一性的類似字段。

因此,比方說,我有能力讓用戶按價格對商品進行分類,但您顯然希望先顯示所有庫存商品。現在讓我們假設你有10萬級的產品,例如,如果你用它進行排序,你將有很多的產品「頁面」普通價時價格

下令:

ORDER BY in_inventory DESC, price ASC 

你可能仍然有問題的用戶在瀏覽頁面時看到相同的產品,因爲沒有給出比價格更具體的標準,並且不能保證超出該標準的排序。

你可能會想要做這樣的事情:

ORDER BY in_inventory DESC, price ASC, unique_id ASC 

這樣的順序是完全可預測的(即使用戶可能根本不知道有排序的唯一的ID被應用)。