2013-11-13 4 views
0

Еще один странный вопрос, который требует немного объяснений, заранее за помощь.Добавление идентификатора магазина в экспорт продукта в opencart (запрос mysql)

Я унаследовал установку opencart, и меня попросили изменить генератор отчетов (Product Export Express), который запускает большой MySQL-запрос, чтобы выплескивать файл xls из всей соответствующей информации о продукте вместе с другими сведениями о данных , Сейчас я использую приведенный ниже код:

<?php 
ini_set("memory_limit","1G"); 
class ModelInventoryExpress extends Model 
{ 


    public function getProducts(){ 
     $products_sql = "SELECT 
     p.product_id AS    `Product ID`, 
     p.model AS     `Model`, 
     p.sku as     `SKU`, 
     pd.name AS     `Product Name`, 
     cd.name as     `Category`, 
     p.location AS    `Location`, 
     p.quantity AS    `Quanity`, 
     (SELECT `text` 
     FROM product_attribute pa 
     WHERE pa.product_id = p.product_id 
     AND pa.attribute_id = 6) AS `Box Count`, 

     (SELECT `text` 
     FROM product_attribute pa 
     WHERE pa.product_id = p.product_id 
     AND pa.attribute_id = 7) AS `Length`, 

     (SELECT `text` 
     FROM product_attribute pa 
     WHERE pa.product_id = p.product_id 
     AND pa.attribute_id = 5) AS `Ring Gauge`, 

     (SELECT `text` 
     FROM product_attribute pa 
     WHERE pa.product_id = p.product_id 
     AND pa.attribute_id = 4) AS `Strength`, 

     (SELECT `text` 
     FROM product_attribute pa 
     WHERE pa.product_id = p.product_id 
     AND pa.attribute_id = 3) AS `Wrapper`, 

     CASE 
     WHEN p.`status` = 1 
     THEN 'active' 
     ELSE 'non-active' 
     END AS `Status` , 
     md.name as     `Manufacturer`, 
     FORMAT(p.price, 2) as `Price`, 
     FORMAT(p.cost, 2) as `Cost`, 
     FORMAT(p.wholesale, 2) as `Wholesale`,     

     CASE 
     WHEN pts.`store_id` = 0 
     THEN 'StogieBoys.com' 
     WHEN pts.`store_id` = 1 
     THEN 'CigarHeist.com' 
     WHEN pts.`store_id` = 2 
     THEN 'm.stogieboys.com' 
     WHEN pts.`store_id` = 3 
     THEN 'BestCigarStuff.com' 
     WHEN pts.`store_id` = 6 
     THEN 'SBCigarWholesale.com' 
     WHEN pts.`store_id` = 8 
     THEN 'StogieTrade.com' 
     ELSE 'None' 
     END AS       `Store`, 

     CASE 
     WHEN p.`is_dropshipped` = 1 
     THEN 'Yes' 
     ELSE 'No' 
     END AS       `Is Dropshipped`   

     FROM 
     product p, 
     product_description pd, 
     product_to_category ptc, 
     category_description cd, 
     manufacturer md, 
     product_to_store pts 
     WHERE 1 
     AND p.product_id = pd.product_id 
     AND p.product_id = ptc.product_id 
     AND ptc.category_id = cd.category_id 
     AND p.manufacturer_id = md.manufacturer_id 
     AND p.product_id = pts.product_id 
     ORDER BY pd.name   
     "; 
     $query = $this->db->query($products_sql); 
     return $query->rows; 
    } 
} 

По большей части это прекрасно работает. Там, где это не удается, находится часть store_id. CASE вернет только первое совпадающее значение, а затем перейдет к следующему бит. Мне нужно, чтобы он соответствовал и перечислял ВСЕ магазины, в которых может отображаться продукт, как и для категории.

Когда выше не работает, я попытался установить его как «категория» АС немного так:

s.name as     `Store`, 

CASE 
WHEN p.`is_dropshipped` = 1 
THEN 'Yes' 
ELSE 'No' 
END AS       `Is Dropshipped`   

FROM 
product p, 
product_description pd, 
product_to_category ptc, 
category_description cd, 
manufacturer md, 
store s, 
product_to_store pts 
WHERE 1 
AND p.product_id = pd.product_id 
AND p.product_id = ptc.product_id 
AND ptc.category_id = cd.category_id 
AND p.manufacturer_id = md.manufacturer_id 
AND p.product_id = pts.product_id 
AND pts.store_id = s.store_id 
ORDER BY pd.name  

Но это не работает, как ожидалось, потому что в магазине таблицы магазина по умолчанию равно 0, и эта таблица начинается с других магазинов множества хранилищ. И.Е. 1 и т. Д., Но не содержит список по умолчанию или 0.

Каким будет лучший способ модерировать этот запрос, чтобы получить результаты, на которые я надеюсь?

+0

Возникли проблемы понимания вашей логики "мне это нужно, чтобы соответствовать и перечислить все магазины, которые продукт может появиться, так же, как и для категории ». Я предполагаю, что «store_id» содержит только одно значение хранилища ... вы ожидаете, что на каждый продукт будет возвращено несколько строк, по одному для каждого магазина ... или? ... (как побочная заметка, не позволяйте утверждениям вашего дела расти этот большой ... создайте справочную таблицу и присоединитесь к ней вместо этого. Легче будущее управление там) – Twelfth

+0

Я написал это на выходе из двери вчера, извините, это немного грубо понять. Я ожидаю возвращения нескольких строк, по одному для каждого хранилища. 'cd.name как' Category', ' делает то, что я ищу. Но я не мог заставить его работать с store_id. Это поле имеет список из 5 возможных номеров и null для значения по умолчанию. Было ли это достаточно разъяснений? Я мог бы продолжить некоторое время – DieselPoweredNun

ответ

1

О человек, вы когда-нибудь слышали о JOIN (LEFT, RIGHT, OUTER, ...)?

Ваш огромный запрос является очень хорошим примером , как это сделать неправильно, и вот пример того, как это должно быть сделано правильный путь:

public function getProducts() { 
    // retrieve products with basic data 
    $products = $this->db->query("SELECT 
    p.product_id    `Product ID`, 
    p.model     `Model`, 
    p.sku      `SKU`, 
    pd.name     `Product Name`, 
    cd.name     `Category`, 
    p.location    `Location`, 
    p.quantity    `Quanity`, 
    p.`status`    `Status` , 
    md.name     `Manufacturer`, 
    FORMAT(p.price, 2)  `Price`, 
    FORMAT(p.cost, 2)   `Cost`, 
    FORMAT(p.wholesale, 2) `Wholesale`,     
    pts.`store_id`   `Store`, 
    p.`is_dropshipped`  `Is Dropshipped`   

    FROM product p, 
     LEFT JOIN product_description pd ON pd.product_id = p.product_id AND pd.language_id = " . (int)$this->config->get('config_language_id') . " 
     LEFT JOIN product_to_category ptc ON ptc.product_id = p.product_id, 
     LEFT JOIN category_description cd ON cd.category_id = ptc.category_id AND cd.language_id = " . (int)$this->config->get('config_language_id') . " 
     LEFT JOIN manufacturer m ON m.manufacturer_id = p.manufacturer_id 
     LEFT JOIN product_to_store pts ON pts.product_id = p.product_id 

    ORDER BY pd.name")->rows; 

    foreach($products as $key => $product) { 
     $products[$key]['Box Count'] = $this->getProductAttributeValue($product['product_id'], 6); 
     $products[$key]['Length']  = $this->getProductAttributeValue($product['product_id'], 7); 
     $products[$key]['Ring Gauge'] = $this->getProductAttributeValue($product['product_id'], 5); 
     $products[$key]['Strength'] = $this->getProductAttributeValue($product['product_id'], 4); 
     $products[$key]['Wrapper'] = $this->getProductAttributeValue($product['product_id'], 3); 
    } 

    return $products; 
} 

public function getProductAttributeValue($product_id, $attribute_id) { 
    $query = $this->db->query("SELECT `text` 
    FROM product_attribute pa 
    WHERE pa.product_id = " . (int).$product_id . " 
    AND pa.attribute_id = " . (int)$attribute_id); 

    return $query->row['text']; 
} 

Как Вы можете упомянуть, I удалил все из CASE WHEN из SQL, так как эти логические интерпретации status, store_id и т. д. должны быть выполнены в вашем шаблоне или контроллере. SQL запросы (и модель), должны только получать и хранить данные и Вы должны сделать ваши запросы SQL как можно проще ... И вспомните использование LEFT JOIN с ...

И 0 магазина (который был бы NULL или нет значение в ваших продуктах), конечно, отобразите правильное имя магазина. Это не 0 (ноль), но NULL, но простая проверка:..

if($product['store_id']) { 
    // we have store_id 
} else { 
    // store_id is not set (NULL), display as the main store 
} 

хватило бы здесь ...

+0

Во-первых, ничего себе. Спасибо, я думаю. Мне потребуется время, чтобы пройти через это, чтобы я понял, что происходит, поэтому, пожалуйста, будьте терпеливы. Я все еще очень новичок в вызовах SQL, поэтому я слышал об этом, но мало знаю о том, как они работают или что они делают. Я узнаю о командах, так как я призван их использовать. Поскольку я делаю сейчас ;-) Во-вторых, я полагаю, что я упомянул, что унаследовал это, поэтому моя попытка добавить store_id к выходу, который я работал в существующей структуре, независимо от того, насколько ошибочен. Добавление цены, стоимости и оптовой торговли - это все, что я действительно сделал для этого, до сих пор. – DieselPoweredNun

+0

В-третьих: Еще раз спасибо за помощь. Я буду делать немного googling, а затем тестирую это, чтобы увидеть, как это работает. В-четвертых: Это утверждение if в конце вашего полезного разговора, как это должно быть реализовано? Поскольку 99% возвращенных предметов будут иметь NULL, многие из них имеют до 3 значений. Спасибо, что помогли этой старой собаке узнать новые трюки. – DieselPoweredNun

+0

'Ошибка анализа: синтаксическая ошибка, неожиданная '.' в /home2/theciga2/public_html/stogieboys/admin/model/inventory/express.php в строке 48' - ошибка, возникающая при попытке кода как есть. Я попытался удалить. перед $ product в указанной строке, но все, что я получаю после этого, - пустой экран и ничего в журнале ошибок. Вот почему я работал в существующей структуре, а не начинал с нуля ;-) Благодарим вас за указание бит JOIN, который пригодится теперь, когда я знаю, что он делает. – DieselPoweredNun

Смежные вопросы