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!
Related
I got a query that blows my head off for about 2 days, and I need some help. Pleeeaaze !
What I need to do is get data form described tables below and the output must display every message for each application using filters on customer.(name, codeX/Y/Z), application.(name, wave), migrationLabel.label, migrationMessage.(dates) using pagination (50 per pages).
Each application can display 0 to n messages and I have to make an HTML table using attribute "rowspan".
Here are the tables :
"# : PK"
"# : FK"
application(#id, label, #customerId)
customer(#id, name, codeX, codeY, codeZ)
erpApplication(#id, label, #customerId)
migrationMessage(#applicationId, creationTime, closureDate, previsionalDate, #labelId, #authorId)
migrationLabel(#id, label, ordering)
works(#employeeId, #applicationId, #roleId)
employee(#id, username)
Here is the current Query :
<?php
$query = 'SELECT
c.id AS customerId, c.name AS customerName, c.X3Code, c.mfgProCode, c.as400Code, c.jdeCode,
a.id AS appId, a.label AS appName, a.wave,
mm.closureDate, mm.previsionalDate, mm.content,
ml.id, ml.label,
q.msgCount
FROM (
SELECT a.id
FROM `application` a
JOIN `customer` c ON c.id = a.customerId
ORDER BY c.name
) l
JOIN application a ON a.id = l.id
JOIN `customer` c ON c.id = a.customerId
LEFT JOIN (
SELECT applicationId, COUNT(*) AS msgCount
FROM application a
JOIN migrationMessage mm ON mm.applicationId = a.id
JOIN migrationLabel ml ON ml.id = mm.labelId
JOIN customer c ON c.id = a.customerId
' . $where . '
GROUP BY applicationId
LIMIT ' . $limit . ' OFFSET ' . $offset . '
) q ON q.applicationId = a.id
LEFT JOIN `migrationMessage`mm ON mm.applicationId = q.applicationId
LEFT JOIN `migrationLabel` ml ON ml.id = mm.labelId
JOIN `works` w ON w.applicationId = a.id '
. ($user->isOperator() ? ' AND w.roleId = ' . Role::Rri : ' AND w.employeeId = ' . $user->id)
. ' JOIN employee e ON e.id = w.employeeId'
. ($user->isJustUser() ? ' AND e.siteId = ' . $user->siteId : '')
. $where
. ' ORDER BY c.name, a.label, ml.ordering'
. 'LIMIT ' . $limit . ' OFFSET ' . $offset;
Almost everything works using this query, the problem happens when I got an application with several messages which get itself on 2 pages...
For example, "rowspan" (msgCount in the query) is 5 but the 3 last messages are on a different page than the first 2 and then the HTML display is completely erroneous. See HTML result
I wrote my query from scratch and come with a result that completely fit my needs.
For those who wondered, the key is the RIGHT JOIN'ed query :
<?php
$query = 'SELECT
c.id AS customerId, c.name AS customerName, c.X3Code, c.mfgProCode, c.as400Code, c.jdeCode,
a.id AS appId, a.label AS appName, a.wave,
mm.closureDate, mm.previsionalDate, mm.content,
ml.id, ml.label,
q0.msgCount
FROM application a
JOIN customer c ON c.id = a.customerId
LEFT JOIN migrationMessage mm ON mm.applicationId = a.id
LEFT JOIN migrationLabel ml ON ml.id = mm.labelId
JOIN `works` w ON w.applicationId = a.id '
. ($user->isOperator() ? ' AND w.roleId = ' . Role::Rri : ' AND w.employeeId = ' . $user->id)
. ' JOIN employee e ON e.id = w.employeeId'
. ($user->isJustUser() ? ' AND e.siteId = ' . $user->siteId : '')
. ' LEFT JOIN (
SELECT applicationId, COUNT(*) AS msgCount
FROM application a
JOIN migrationMessage mm ON mm.applicationId = a.id
JOIN migrationLabel ml ON ml.id = mm.labelId
JOIN customer c ON c.id = a.customerId
GROUP BY applicationId
) q0 ON q0.applicationId = a.id
RIGHT JOIN (
SELECT a.id
FROM application a
JOIN customer c ON c.id = a.customerId
LEFT JOIN migrationMessage mm ON mm.applicationId = a.id
LEFT JOIN migrationLabel ml ON ml.id = mm.labelId
' . $where . '
GROUP BY a.id
ORDER BY c.name, a.label, ml.ordering
LIMIT ' . $limit . ' OFFSET ' . $offset . '
) q1 ON q1.id = a.id
ORDER BY c.name, a.label, ml.ordering'
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)
I have been trying to do a sum with a join with no luck. What I need is to get a total from product_price (located in tbl_products) based on a product_id which is located in both tbl_basket and tbl_products.
So far I have:
$result = mysql_query("SELECT * FROM tbl_basket a INNER JOIN tbl_products b ON a.product_id = b.product_id WHERE a.customer_id = '" . $_SESSION['user'] . "'");
This works to get the product_name from tbl_products based on the product_id stored in tbl_basket. I know I need a COUNT which I have tried numerous ways but with no luck. I have chosen to show a query I know works for something as my syntax for the COUNT I tried was way off. Thank you.
Does this not work?
$result = mysql_query("SELECT sum(b.product_price) as total_price FROM tbl_basket a INNER JOIN tbl_products b ON a.product_id = b.product_id WHERE a.customer_id = '" . $_SESSION['user'] . "'")
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
I have a list of venues in the Venues table, and a list of a cities/states in the Locations table. The venue is associated with an area code unique to my organization, referred to as a SOYID. The SOYID is made up of a geographical area - each row in the Locations table has a City, State, and the corresponding SOYID. Some Venues rows have a SOYID, others do not; for those that do not, I need to find the SOYID for the city and state listed. I only want to select those Venues in a specific SOYID.
This query works, however, it takes a few seconds to load; I don't think I am writing the query correctly. Currently Venues has approx 140 rows, Locations has 40,000.
$sql = "SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
FROM Venues AS a LEFT JOIN Locations AS c ON a.City = c.city
WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
OR ((c.city = a.City) AND (c.state = a.StateAbbr) AND (c.SOYID = '" . mysql_real_escape_string($SOYID) . "'))
ORDER BY a.Name ASC";
Any time you reference a column from a LEFT JOINed table (c.state and c.SOYID in your specific case) in the WHERE clause, you force that join to behave like an INNER JOIN. Instead, make those tests part of the join condition:
"SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
FROM Venues AS a
LEFT JOIN Locations AS c
ON a.City = c.city
AND a.StateAbbr = c.state
AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "'
WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
OR c.SOYID IS NOT NULL /* LEFT JOIN found a matching row */
ORDER BY a.Name ASC"
EDIT: Based on comments, this version should allow you do remove the DISTINCT requirement:
"SELECT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
FROM Venues AS a
WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
OR EXISTS(SELECT NULL
FROM Locations AS c
WHERE a.City = c.city
AND a.StateAbbr = c.state
AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "')
ORDER BY a.Name ASC"