I have this query
$query = "SELECT * FROM items WHERE itemStatus = '1' AND itemAdded > '$timestamp'";
Once this query has returned results I loop through the results
the results array is itemID, itemLocationID, categoryParentID, categoryID, itemName, itemDetails
During the loop I then run three other queries by calling functions within the same class
$locationName = $this->getLocationByName($locationID);
$categoryParentName = $this->getCategoryByName($categoryParentID);
$categoryName = $this->getCategoryByName($categoryID);
the function getLocationByName performs this query;
$q = mysql_query("SELECT * FROM locations WHERE locationID = '$locationID'");
this returns an array of locationID, locationName, locationLink
the function getCategoryByName performs this query;
$q = mysql_query("SELECT * FROM categories WHERE categoryID = '$categoryID'");
this returns an array of categoryID, categoryName, categoryLink
Could someone please help me optimize this query and maybe join them to save doing so many queries.
thanks in advance.
Im now using this query
$q = mysql_query("SELECT
i.itemID,
i.locationID,
i.categoryParentID,
i.categoryID,
i.itemName,
i.itemDetails,
l.*,
c.*
FROM items i inner join locations l on i.locationID = l.locationID inner join categories c on i.categoryID = c.categoryID WHERE itemStatus = '1' AND itemAdded > '$timestamp'")or die(mysql_error());
and the result is
Array
( [itemID] => 81300 [locationID] => 17 [categoryParentID] => 21 [categoryID] => 183 [itemName] => blah [itemDetails] => blah [locationName] => brilliant it pulls in the location as expected. [locationLink] => blah [categoryName] => brilliant it pulls in the category as expected. [categoryLink] => blah )
[categoryName] => //these are missing for categoryParentID
[categoryLink] => //these are missing for categoryParentID
I think should be something similar to below query. I do not see where are you using $categoryParentName .
Using your queries and data:
SELECT * FROM items WHERE itemStatus = '1' AND itemAdded > '$timestamp'
SELECT * FROM locations WHERE locationID = '$locationID'
SELECT * FROM categories WHERE categoryID = '$categoryID'
$locationName = $this->getLocationByName($locationID);
$categoryParentName = $this->getCategoryByName($categoryParentID);
$categoryName = $this->getCategoryByName($categoryID);
Please let me know if this returns expected result set. Hope this helps
SELECT
it.itemID, it.itemLocationID, it.categoryParentID, it.categoryID, it.itemName, it.itemDetails,
l.locationID, l.locationName, l.locationLink,
c.categoryID, c.categoryName, c.categoryLink
FROM items it
LEFT JOIN locations l ON l.locationID = it.itemLocationID
LEFT JOIN categories c ON c.categoryID = it.categoryID
WHERE
it.itemStatus = '1'
AND it.itemAdded > '$timestamp'
Update query using categoryParentID - i am not saying is efficient but you can test and optimize as needed.
One option is to update above query - not sure that will work - and for large result sets using OR is not efficient:
LEFT JOIN categories c ON (c.categoryID = it.categoryID OR c.categoryID = it.categoryParentID)
The other option that i see is to get 2 result sets (see below) - one for categId = categId and second for categId = categParentId and combine the result set in one big result set.
SELECT
t.itemID, t.itemLocationID, t.categoryParentID, t.categoryID, t.itemName, t.itemDetails,
l.locationID, l.locationName, l.locationLink,
t.categoryID, t.categoryName, t.categoryLink
FROM
(
SELECT
it.itemID, it.itemLocationID, it.categoryParentID, it.categoryID, it.itemName, it.itemDetails,
c.categoryID, c.categoryName, c.categoryLink
FROM items it
INNER JOIN categories c ON c.categoryID = it.categoryID
WHERE
it.itemStatus = '1'
AND it.itemAdded > '$timestamp'
UNION -- [ALL]
SELECT
it.itemID, it.itemLocationID, it.categoryParentID, it.categoryID, it.itemName, it.itemDetails,
c.categoryID, c.categoryName, c.categoryLink
FROM items it
INNER JOIN categories c ON c.categoryID = it.categoryParentID
WHERE
it.itemStatus = '1' AND
it.itemAdded > '$timestamp'
) AS t
LEFT JOIN locations l ON l.locationID = t.itemLocationID
Other idea - not tested and assuming that id are int - will have to cast as string / char. There are a few options how you can write this query - if you post a structure table and some dummy data i am sure that someone will create a demo / sqlfiddle.
SELECT
it.itemID, it.itemLocationID, it.categoryParentID, it.categoryID, it.itemName, it.itemDetails,
l.locationID, l.locationName, l.locationLink,
c.categoryID, c.categoryName, c.categoryLink
FROM items it
LEFT JOIN locations l ON l.locationID = it.itemLocationID
WHERE
it.itemStatus = '1'
AND it.itemAdded > '$timestamp'
AND c.category ID IN ( SELECT GROUP_CONCAT(categs) FROM (SELECT CONCAT(categoryID, ",", categoryParentID) AS categs FROM items ))
I would not use * in the select statement The Query with the joins could be
SELECT
i.itemID,
i.itemLocationID,
i.categoryParentID,
i.categoryID,
i.itemName,
i.itemDetails,
l.*,
c.*
FROM
items i
inner join locations l on i.itemLocationID = l.locationID
inner join categories c on i.categoryID = c.categoryID
WHERE
itemStatus = '1'
AND itemAdded > '$timestamp'
I hope it be useful for you. Cheers!
Unless I'm missing something obvious, I'd probably suggest something like this as a first start:
select *
from items i
join locations l
on i.location_id=l.location_id
join categories c
on i.category_id=c.category_id
where item_status='1'
and itemAdded > '$timestamp'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.