3

Magento で「持つ」SQL 関数が必要です。私の知る限り、having 関数はありません。

だから私はコレクションクラスでそれを実装しようとします

 public function addAttributeHaving($attribute)
 {
      $this->getSelect()->having($attribute); 
      return $this;
 } 

そして、この機能を使用すると

 $collectionHotel->addAttributeToSort($order, $dir)
                 ->addAttributeHaving('MIN(`apptha_booking_room_types`.`room_price_per_night`) >= '.$lowestprice)
                ->addAttributeHaving('MIN(`apptha_booking_room_types`.`room_price_per_night`) <= '.$highestprice); 

出力クエリは問題ありません:

SELECT 
    `e` . *,
    MIN(`apptha_booking_room_types`.room_price_per_night) AS `lowestprice`,
    IF(at_status.value_id > 0,
        at_status.value,
        at_status_default.value) AS `status`,
    IF(at_apptha_hotel_period_to.value_id > 0,
        at_apptha_hotel_period_to.value,
        at_apptha_hotel_period_to_default.value) AS `apptha_hotel_period_to`,
    `price_index`.`price`,
    `price_index`.`tax_class_id`,
    `price_index`.`final_price`,
    IF(price_index.tier_price IS NOT NULL,
        LEAST(price_index.min_price,
                price_index.tier_price),
        price_index.min_price) AS `minimal_price`,
    `price_index`.`min_price`,
    `price_index`.`max_price`,
    `price_index`.`tier_price`
FROM
    `catalog_product_entity` AS `e`
        LEFT JOIN
    `apptha_booking_room_types` ON (apptha_booking_room_types.entity_id = e.entity_id)
        INNER JOIN
    `catalog_product_entity_int` AS `at_status_default` ON (`at_status_default`.`entity_id` = `e`.`entity_id`)
        AND (`at_status_default`.`attribute_id` = '89')
        AND `at_status_default`.`store_id` = 0
        LEFT JOIN
    `catalog_product_entity_int` AS `at_status` ON (`at_status`.`entity_id` = `e`.`entity_id`)
        AND (`at_status`.`attribute_id` = '89')
        AND (`at_status`.`store_id` = 1)
        INNER JOIN
    `catalog_product_entity_datetime` AS `at_apptha_hotel_period_to_default` ON (`at_apptha_hotel_period_to_default`.`entity_id` = `e`.`entity_id`)
        AND (`at_apptha_hotel_period_to_default`.`attribute_id` = '168')
        AND `at_apptha_hotel_period_to_default`.`store_id` = 0
        LEFT JOIN
    `catalog_product_entity_datetime` AS `at_apptha_hotel_period_to` ON (`at_apptha_hotel_period_to`.`entity_id` = `e`.`entity_id`)
        AND (`at_apptha_hotel_period_to`.`attribute_id` = '168')
        AND (`at_apptha_hotel_period_to`.`store_id` = 1)
        INNER JOIN
    `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id
        AND price_index.website_id = '1'
        AND price_index.customer_group_id = 0
WHERE
    (`e`.`type_id` = 'hotel')
        AND (IF(at_status.value_id > 0,
        at_status.value,
        at_status_default.value) = '1')
        AND (IF(at_apptha_hotel_period_to.value_id > 0,
        at_apptha_hotel_period_to.value,
        at_apptha_hotel_period_to_default.value) >= '2012-11-09')
GROUP BY `e`.`entity_id`
HAVING (MIN(`apptha_booking_room_types`.`room_price_per_night`) >= 0)
    AND (MIN(`apptha_booking_room_types`.`room_price_per_night`) <= 999999999)
ORDER BY `lowestprice` asc

このクエリを MySQL で実行すると、出力は問題ありません。

しかし、私が使用しようとすると

 $collectionHotel->load(); 

このエラーが表示されます:

SQLSTATE[42S22]: 列が見つかりません: 1054 不明な列 'apptha_booking_room_types.room_price_per_night' in 'having clause'</p>

できることはすべて試しましたが、まだこの問題を解決できません。誰でも助けることができますか?

あるいは、having() 関数を実装するより良い方法はありますか?

4

5 に答える 5

2

これまでのところ、これはmagentoのバグだと思います..まあ...私の問題はいくつかのトリックを使用して解決しました..しかし、出力クエリは良好ですが、magentoは常に未知の列と言うため、この方法は使用しません。

于 2012-11-13T01:17:04.170 に答える
0

データベースに対してSQLを手動で実行してみて、この行を変更してください

....
HAVING (MIN(`apptha_booking_room_types`.`room_price_per_night`) >= 0)
   AND (MIN(`apptha_booking_room_types`.`room_price_per_night`) <= 999999999)

.....
HAVING (`lowestprice` >= 0)
   AND (`lowestprice` <= 999999999)

上記のコードが機能する場合は、これを変更してみてください

->addAttributeHaving('`lowestprice` >= '.$lowestprice)
->addAttributeHaving('`lowestprice` <= '.$highestprice);
于 2012-11-12T01:31:40.613 に答える
0

残念ながら、これは Magento のバグです。私は同じ問題を抱えていて、管理エリアのグリッド表示用のデータを取得するためだけに、2 番目の DB モデル クラスを作成することになりました。

2 番目の Collection.php ファイルのコンストラクター メソッドで、直接 DB クエリを使用して mysql VIEW を作成し、元のテーブルから (group by 句を使用して) データを選択して結果を一時的にキャッシュしました。

構成メソッドでは:

            $resource = Mage::getSingleton('core/resource');
            $writeConnection = $resource->getConnection('core_write');

            $sql = "
                   CREATE OR REPLACE VIEW your_temp_view_name AS
                   SELECT SUM(column_name) as column_name
                   FROM original_table_name
                   WHERE ...
                   GROUP BY customer_id
            ";

            $writeConnection->query($sql);

データはすでにグループ化されており、集計関数はすでに実行されているため、通常の addAttributeToFilter メソッドを使用してデータをフィルタリングできます。

少しハックですが、この場合はうまくいきました。データの量と同時ユーザーの量に応じて、機能する場合と機能しない場合があります。

于 2015-03-22T16:40:54.500 に答える
0

まず第一に、コレクションから$countSelect->reset(Zend_Db_Select::HAVING);リセットされることを意味HAVINGします。つまり、having 句が削除されます。そして、それはあなたが望むものではありません。コレクションに追加することをお勧めします (app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php->_getSelectCountSql()こちら)。

しかし、主な原因はファイルgetSize()に存在するメソッドです。lib/Varien/Data/Collection/Db.php

インターネットで利用可能なほとんどすべてのソリューションを試しましたが、どれもうまくいきませんでした。

今、私は以下を行いました。

public function getSize()
{
    if (is_null($this->_totalRecords)) {
        //$sql = $this->getSelectCountSql();
        $sql = $this->getSelect();
        $this->_totalRecords = count($this->getConnection()->fetchAll($sql, $this->_bindParams));
    }
    return intval($this->_totalRecords);
}

を使用していないことを確認してくださいgetSelectCountSql()SQL QUERY全体を読み取ってすべてのデータを取得し、その数を返しています。それで全部です。

于 2016-11-01T18:03:37.637 に答える
0

having 句と order 句の別の書き方

$product_log_data = Mage::getModel('customtabs/productlog')->getCollection();
 $product_log_data->getSelect()->having(
            "rowNumber = 1" );
 $product_log_data->getSelect()->order(
            "rowNumber" );
于 2014-09-11T07:09:13.297 に答える