ปัญหาในการใช้“ การมี” ในชุดวีโอไอพี


20

ฉันกำลังพยายามสร้างคอลเลกชันที่กำหนดเองสำหรับกริดในโมดูลผู้ดูแลระบบของวีโอไอพี ฉันได้สร้างวิธีการรวบรวมใหม่ที่เรียกว่า "addAttributeHaving" ซึ่งทำต่อไปนี้:

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

ดูรหัสสะสม:

$collection->addFieldToSelect(
    array(
        'entity_id',
        'created_at',
        'increment_id',
        'customer_email',
        'customer_firstname',
        'customer_lastname',
        'grand_total',
        'status'
    )
);

$collection->getSelect()->joinLeft(array('sfop' => 'sales_flat_order_payment'), 'main_table.entity_id = sfop.parent_id', 'sfop.amount_authorized');
$collection->getSelect()->columns('sum(sfop.amount_authorized) AS AUTHD');
$collection->getSelect()->columns('grand_total - sum(sfop.amount_authorized) AS DIF_AU');
$collection->addFieldToFilter('main_table.state', array('in' => array('new','payment_review')));
$collection->addFieldToFilter('main_table.sd_order_type', array('neq' => 7));
$collection->addFieldToFilter('sfop.method', array('neq' => 'giftcard'));
$collection->addFieldToFilter('main_table.created_at', array('gt' => $this->getFilterDate()));
$collection->getSelect()->group(array('main_table.entity_id'));
$collection->addAttributeHaving('DIF_AU <> 0');
$collection->load(true,true);

$this->setCollection($collection);

สิ่งนี้สร้าง SQL ต่อไปนี้ซึ่งทำงานได้อย่างสมบูรณ์แบบและสร้างผลลัพธ์ที่คาดหวังเมื่อทำงานนอก Magento

[METHOD=Varien_Data_Collection_Db->printLogQuery] SELECT `main_table`.`entity_id`, `main_table`.`entity_id`, `main_table`.`created_at`, `main_table`.`increment_id`, `main_table`.`customer_email`, `main_table`.`customer_firstname`, `main_table`.`customer_lastname`, `main_table`.`grand_total`, `main_table`.`status`, `sfop`.`amount_authorized`, sum(sfop.amount_authorized) AS `AUTHD`, grand_total - sum(sfop.amount_authorized) AS `DIF_AU` FROM `sales_flat_order` AS `main_table` LEFT JOIN `sales_flat_order_payment` AS `sfop` ON main_table.entity_id = sfop.parent_id WHERE (main_table.state in ('new', 'payment_review')) AND (main_table.sd_order_type != 7) AND (sfop.method != 'giftcard') AND (main_table.created_at > '2013-04-07') GROUP BY `main_table`.`entity_id` HAVING (DIF_AU <> 0)

อย่างไรก็ตามเมื่อฉันพยายามโหลดกริดภายใน Magento ฉันได้รับข้อผิดพลาดดังต่อไปนี้:

SQLSTATE [42S22]: ไม่พบคอลัมน์: 1054 คอลัมน์ที่ไม่รู้จัก 'DIF_AU' ใน 'มีประโยค'

นอกจากนี้หากฉันลบประโยคที่มี (ซึ่งทำลายผลลัพธ์ของฉัน) ฉันสามารถใช้คอลัมน์ DIF_AU สำหรับแหล่งข้อมูลในกริด


1
UPDATE: ฉันสามารถติดตามปัญหาไปยังเมธอด getSelectCountSql () หลักได้ นี่คือปัญหาที่เกิดขึ้นจริงเมื่อพยายามรับจำนวนการรวบรวม
แอนโทนี่กรองจูเนียร์

1
โพสต์คำตอบ! WTH นั้นsd_order_typeมาจากไหน?
benmarks

1
สิ่งที่ประเภทคำสั่งซื้อที่กำหนดเองลับสุดยอดที่ถูกเพิ่มไปยังตารางแบน ฉันยังคงหาคำตอบอยู่
Anthony Leach Jr

1
"ผู้ใช้ที่มีชื่อเสียงน้อยกว่า 10 คนไม่สามารถตอบคำถามของตนเองเป็นเวลา 8 ชั่วโมงหลังจากถามคุณสามารถตอบได้ภายใน 7 ชั่วโมงจนกว่าจะถึงเวลาโปรดใช้ความคิดเห็นหรือแก้ไขคำถามของคุณแทน" (ทางออกที่จะมาใน 7 ชั่วโมง)
Anthony Leach Jr

1
ใครบางคนให้การ
โหวต

คำตอบ:


12

ฉันจะตอบคำถามของฉันเองที่นี่ ฉันรู้ว่าไม่มีรสนิยมที่ดี แต่ฉันสะดุดคำตอบเมื่อมองใกล้ที่กองติดตามจริง คอลเลกชันคือการโหลดที่ดี แต่ความล้มเหลวมาเล็ก ๆ น้อย ๆ ต่อมาในการดำเนินการเมื่อเราพยายามที่จะได้รับการนับคอลเลกชันในVarien_Data_Collection_Db :: getSelectCountSql () SQL ที่ผลิตจากสิ่งนี้คือ:

SELECT COUNT(*) FROM sales_flat_order AS main_table LEFT JOIN sales_flat_order_payment AS sfop ON main_table.entity_id = sfop.parent_id WHERE (main_table.state in ('payment_review')) AND (main_table.sd_order_type != 7) AND (sfop.method != 'giftcard') AND (main_table.created_at > '2013-04-07') GROUP BY main_table.entity_id HAVING (DIF_AU <> 0)

คุณจะสังเกตเห็นว่ามีการแนบคำสั่ง HAVING แล้วแต่เราไม่มีคำนิยามสำหรับคอลัมน์ DIF_AU อีกต่อไป ดูเหมือนว่าฉันจะต้องขยาย getSelectCountSql () ที่กำหนดเองในคลาสคอลเลกชันของฉันเพื่อรับจำนวนระเบียนที่ถูกต้อง

ฉันได้สร้าง getSelectCountSql () เพิ่มเติมในคลาสคอลเล็กชันที่กำหนดเองซึ่งเพิ่มกลับมาในคอลัมน์ที่ขาดหายไปซึ่งจำเป็นสำหรับคำสั่งที่มี


public function getSelectCountSql()
  {
    $countSelect = parent::getSelectCountSql();
    $countSelect->columns('grand_total - sum(sfop.amount_authorized) AS DIF_AU');
    $countSelect->reset(Zend_Db_Select::GROUP);
    return $countSelect;
  }

1
ไม่ยุ่งเหยิงเลย…หากคุณคิดวิธีแก้ปัญหาก่อน คนอื่น ๆ อาจพบว่ามีประโยชน์ตามถนน +1 :)
davidalger

คุณควรยื่นรายงานข้อผิดพลาด! magentocommerce.com/bug-tracking
benmarks

นี่คือปัญหาที่ผมยังได้เห็นและทำได้ดีในการหาคำตอบ อย่างไรก็ตามฉันไม่คิดว่าโซลูชันของคุณถูกต้องเนื่องจากคุณใช้กลุ่มโดย SelectCountSql ของคุณต้องส่งคืนจำนวนกลุ่ม ดังนั้นคุณต้องมีจำนวน (fetchAll ()) หรือเขียนคำค้นหาของคุณโดยใช้count(distinct main_table.entity_id)แทนcount(*)
Benubird

ฉันคิดว่าคุณน่าจะถูกต้องมาก โครงการนี้ได้รับในเตาหลังตั้งแต่โพสต์นี้และเพียงแค่ตอนนี้ได้รับกลับไป ในการสาธิตเมื่อสัปดาห์ที่แล้วผมสังเกตเห็นนับบันทึกที่ไม่ถูกต้องมีการรายงานในตาราง จะรายงานการค้นพบของฉันอีกครั้งเมื่อฉันได้รับการแก้ไขแล้ว
Anthony Leach Jr

@AnthonyLeachJr ข่าวใด ๆ เกี่ยวกับการค้นพบของคุณหรือไม่
Simon

0

ก่อนอื่น$countSelect->reset(Zend_Db_Select::HAVING);จะเป็นการรีเซ็ตHAVINGจากคอลเล็กชันของคุณ นั่นหมายความว่ามันจะลบประโยคที่มีอยู่ และไม่ใช่สิ่งที่คุณต้องการ คุณอาจต้องการเพิ่มลงในคอลเล็กชัน ( app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php->_getSelectCountSql()ที่นี่)

แต่ผู้ร้ายหลักมันเป็นgetSize()วิธีการที่มีอยู่ในlib/Varien/Data/Collection/Db.phpไฟล์

ฉันพยายามแก้ปัญหาดังกล่าวข้างต้นโดย @Anthony แต่ที่ไม่ได้ทำงาน

ตอนนี้ฉันทำด้านล่าง

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และเรียกข้อมูลทั้งหมดและกลับมานับหนึ่งของมัน นั่นคือทั้งหมดที่


0

ฉันแก้ไขปัญหานี้ได้ที่นี่: แอป / รหัส / คอร์ / ผู้วิเศษ / แคตตาล็อก / โมเดล / ทรัพยากร / ผลิตภัณฑ์ / Collection.php: 943 เพิ่มสิ่งนี้: $ select-> รีเซ็ต (Zend_Db_Select :: HAVING);

เพียงคัดลอกแอป / รหัส / คอร์ / Mage / แคตตาล็อก / โมเดล / ทรัพยากร / ผลิตภัณฑ์ / Collection.php ไปยังแอป / รหัส / โลคอล / Mage / แคตตาล็อก / โมเดล / ทรัพยากร / ผลิตภัณฑ์ / Collection.php

รหัสของฉันตอนนี้ดูเหมือนว่านี้:

/**
 * Build clear select
 *
 * @param Varien_Db_Select $select
 * @return Varien_Db_Select
 */
protected function _buildClearSelect($select = null)
{
    if (is_null($select)) {
        $select = clone $this->getSelect();
    }
    $select->reset(Zend_Db_Select::ORDER);
    $select->reset(Zend_Db_Select::LIMIT_COUNT);
    $select->reset(Zend_Db_Select::LIMIT_OFFSET);
    $select->reset(Zend_Db_Select::COLUMNS);
    $select->reset(Zend_Db_Select::HAVING);

0

โซลูชันนี้จะทำงานหากการเลือกของคุณมีชื่อคอลัมน์ที่ไม่ซ้ำกันเนื่องจากคอลัมน์ใด ๆ ในรายการการสืบค้นย่อยจะต้องมีชื่อที่ไม่ซ้ำกัน

แบบสอบถามย่อย: แบบสอบถามย่อยตารางช่วยให้ชื่อคอลัมน์ที่ซ้ำกัน

public function getSelectCountSql()
{
    $this->_renderFilters();
    $select = clone $this->getSelect();
    $select->reset(Zend_Db_Select::ORDER);
    $select->reset(Zend_Db_Select::LIMIT_COUNT);
    $select->reset(Zend_Db_Select::LIMIT_OFFSET);        

    $countSelect = clone $this->getSelect();
    $countSelect->reset();
    $countSelect->from(array('a' => $select), 'COUNT(*)');
    return $countSelect;
}

PS: คำตอบนี้สำหรับคอลเลกชันวีโอไอพีทั่วไป ไม่เกี่ยวข้องกับการรวบรวมผลิตภัณฑ์เท่านั้น


0

นี่มันใช้งานได้ดี

ฟังก์ชั่นที่สาธารณะ getSize () {ถ้า (is_null ($ นี้ -> _ totalRecords)) {// $ sql = $ this-> getSelectCountSql (); $ sql = $ this-> getSelect (); $ this -> _ totalRecords = count ($ this-> getConnection () -> fetchAll ($ sql, $ this -> _ bindParams)); } คืน intval ($ this -> _ totalRecords); }

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.