I want to get all products from opencart - php

I need a query to get all products from opencart mysql. I am using this query.
"SELECT * FROM `" . DB_PREFIX . "product`";
but I can't get product name or title in this query. Actually I am creating another application and I want to export all products into new DB.

Real sql
SELECT * FROM oc_product p LEFT JOIN oc_product_description pd ON (p.product_id = pd.product_id) WHERE pd.language_id = '1' GROUP BY p.product_id ORDER BY pd.name ASC
First take oc_ into consideration as this is DB_PREFIX.
Then take pd.language_id='1' into consideration as it retrieves products only having language_id=1. If there are multiple language then you have to find the language_id and change it.
This is to retrieve all
SELECT * FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id)

Related

How not to overwrite Same columns name when multiple tables are joined SQL?

i have an sql statement that retrives information from multiple tables but some of them have same columns name.
For exemple the products table has the image column which can also be found in the manufacturer table.
I don't want to overwrite the product image with the manufacturer image. I only need to get the name column from the manufacturer table AS "manufacturer" . The rest needs to r
This is my code:
$sql = "SELECT * FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "manufacturer m ON (p.manufacturer_id = m.manufacturer_id) LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "'";
Thank you!

How to make left join on specific rows in right table?

My website may have individual price list for user. When I left join imported product table on all products table I don't know where to put WHERE which would only do left join on specific rows at right table (logged user rows).
I need to do this in opencart, but it doesnt matter, it's just SQL
$sql = "SELECT * FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON
(p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "import i ON (p.ean = i.ean_code) WHERE
i.import_id = '" . (int)$query->row['import_id'] . "'";
I somehow need to do WHERE on import table first, but in example above it does it afterwards. Do I have to execute 2 queries?
Use parameters where you can. You need to move the condition to the on clause:
SELECT *
FROM " . DB_PREFIX . "product p LEFT JOIN
" . DB_PREFIX . "product_description pd
ON p.product_id = pd.product_id LEFT JOIN
" . DB_PREFIX . "import i
ON p.ean = i.ean_code AND
i.import_id = ?
You should also be selecting the explicit column names. This is particularly important in a LEFT JOIN, because the tables share column names (at least product_id) and you don't know which is referenced by "product_id" in the application code.

Opencart 3 products not fetch data mysql query not showing products

I have this query but it's not showing any data, I'm getting blank results:
SELECT * FROM oc_product p
LEFT JOIN oc_product_description pd ON (p.product_id = pd.product_id)
WHERE pd.language_id = '1'
GROUP BY p.product_id
ORDER BY pd.name ASC
I think the problem is in the oc_product_description table (field descriptions).
I try also SELECT * FROM oc_product This working fine, but SELECT * FROM oc_product_description this not working , SELECT name FROM oc_product_description this working fine ...
This is my full code
<?php
// DB
define('DB_DRIVER', 'mysqli');
define('DB_HOSTNAME', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_DATABASE', 'opencart');
define('DB_PORT', '3306');
define('DB_PREFIX', 'oc_');
$db = mysqli_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
if (mysqli_connect_errno()) {
echo 'Database connection failed with following errors: ' . mysqli_connect_error();
die();
}
$products = [];
//$sql = $db->query("SELECT * FROM ". DB_PREFIX ."product p LEFT JOIN " . DB_PREFIX . "product_description pd ON pd.product_id = p.product_id WHERE pd.language_id = 1");
$sql = $db->query("SELECT * FROM oc_product p LEFT JOIN oc_product_description pd ON (p.product_id = pd.product_id) WHERE pd.language_id = '1' GROUP BY p.product_id ORDER BY pd.name ASC");
while ($row = mysqli_fetch_assoc($sql)) {
$products[] = $row;
}
echo json_encode($products);
?>
please help me anyone...thank you
The problem seems to be that you either don't have any matching row for that products in oc_product_description or that the descriptions you have in that table for those products have a value in language_id different of 1.
Although you are using LEFT JOIN for joining the description your WHERE condition is using a column of the table oc_product_description, which is the equivalent of converting it to an INNER JOIN, because the results for all the products without a matching description will have a NULL value for language_id, so the condition WHERE pd.language_id = 1 would be always false.
Check the contents of your description table, also you can rewrite the query in this way to return results also for products without description:
SELECT p.*, IFNULL(pd.name,'(no description found)') as name
FROM oc_product p
LEFT JOIN oc_product_description pd ON p.product_id = pd.product_id AND pd.language_id = 1
GROUP BY p.product_id
ORDER BY pd.name ASC
This works because we moved the condition to the LEFT JOIN so if the condition fails it only affects the join.
Note that if the products table has a column with a default description you could use that column instead of '(no description found)'.

Error on getting information in mysql

I have a public function with query but I don't get all the informations correctly.
public function getNextId($product_id,$product_category_id) {
$query2zz = $this->db->query("
SELECT *
FROM oc_product_to_category a
LEFT
JOIN oc_product b
ON a.product_id = b.product_id
LEFT
JOIN oc_product_description c
ON c.product_id = a.product_id
LEFT
JOIN oc_url_alias d
ON d.query LIKE CONCAT('%', 'a.product_id', '%')
WHERE a.product_id > '" . (int)$product_id . "'
AND a.category_id = '" . (int)$product_category_id . "'
AND b.status = '1'
ORDER
BY a.product_id ASC
LIMIT 1");
The idea is that I want to get next id for a next button. If you visit a product, you can click on next button, and you will go to next product on same category (clothes).
The problem is on oc_url_alias where I should get url for next id, as i mentioned here WHERE a.product_id > '" . (int)$product_id . "' but sometimes it get me wrong url (I mean get url for another product).
Thanks!

MySQL: Show latest value when using GROUP BY

My table "orders" includes the date_purchased and my table "orders_products" includes the products_id for the specific order.
I want to list a specific client's all purchased products_id (not all orders!) showing the latest date_purchased for each products_id. The list should be ordered with the latest orders_id of these at the top.
The code below will show all unique products_id as I want, but the "group by" is resulting in not showing the latest orders_id or date_purchased for each products_id…
What am I missing here?
SELECT o.orders_id, o.date_purchased, op.products_id
FROM orders o, orders_products op
WHERE o.customers_id = '" . $client_id . "' and op.orders_id = o.orders_id
GROUP BY op.products_id
ORDER BY orders_id DESC
The not exists approach is often the most efficient approach for this type of query:
SELECT o.orders_id, o.date_purchased, op.products_id
FROM orders o join
orders_products op
on op.orders_id = o.orders_id
WHERE o.customers_id = '" . $client_id . "' and
not exists (select 1
from orders o2 join
orders_products op2
on op2.orders_id = o2.orders_id
where op2.products_id = op.products_id and
o.customers_id = '" . $client_id . "' and
o2.orders_id > o.orders_id
)
ORDER BY orders_id DESC;
The logic is: "Get me all rows from orders where there is no row with the same product and a larger id." This is equivalent to saying: "Get me the max row".
For best performance, you want an index on orders(products_id, orders_id).
EDIT:
There is another approach that uses subtring_index() and group_concat(). This might be the most efficient way, if the filter on customer_id is highly selective (that is, greatly reduces the number of rows).
SELECT max(o.orders_id) as orders_id,
substring_index(group_concat(o.date_purchased order by orders_id desc), ',', 1) as date_purchased,
op.products_id
FROM orders o join
orders_products op
on op.orders_id = o.orders_id
WHERE o.customers_id = '" . $client_id . "'
GROUP BY op.products_id;
Of course, if the date purchased and orders_id are both increasing, you can simplify this to using max() for both:
SELECT max(o.orders_id) as orders_id,
max(o.date_purchased) as date_purchased,
op.products_id
FROM orders o join
orders_products op
on op.orders_id = o.orders_id
WHERE o.customers_id = '" . $client_id . "'
GROUP BY op.products_id;
Using group by the result will be grouped in un-ordered way you cannot rely on that using group by will give you the latest result in each so for this you need to first get the maximum of purchase date and then join with your orders table with using additional condition in on clause
SELECT
o.orders_id,
o.date_purchased,
oo.products_id
FROM
orders o
INNER JOIN (
SELECT orders.orders_id, MAX(orders.date_purchased) date_purchased ,orders_products.products_id
FROM orders
INNER JOIN
orders_products
ON(orders_products.orders_id = orders.orders_id)
GROUP BY orders.orders_id ,orders_products.products_id
) oo
ON( oo.orders_id = o.orders_id AND oo.date_purchased=o.date_purchased)
WHERE o.customers_id = '" . $client_id . "'
ORDER BY o.orders_id DESC
This will give the latest orders per products of customer
You might try this? Cannot test it right now.
SELECT MAX(o.orders_id), MAX(o.date_purchased), op.products_id
FROM orders o, orders_products op
WHERE o.customers_id = 1 and op.orders_id = o.orders_id
GROUP BY op.products_id

Categories