3

我需要在 Magento 中“拥有”一个 SQL 函数。据我所知,没有功能。

所以我尝试在集合类中实现它

 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' 在“有子句”中</p>

我尽我所能,但我还不能解决这个问题。任何人都可以帮忙吗?

或者,是否有更好的方法来实现 have() 函数?

4

5 回答 5

2

我相信到目前为止,这是magento的一个错误......好吧......我的问题通过使用一些技巧解决了......但不要使用这种方法,因为尽管输出查询很好,但magento总是说未知列。

于 2012-11-13T01:17:04.170 回答
0

不幸的是,这是 Magento 中的一个错误。我遇到了同样的问题,最后创建了第二个数据库模型类,只是为了检索管理区域网格显示的数据。

在第二个 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 方法来过滤数据。

这有点hacky,但它在这种情况下有效。根据数据量和同时使用的用户数量,它可能有效,也可能无效。

于 2015-03-22T16:40:54.500 回答
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

编写有和顺序子句的另一种方法

$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 回答
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 回答