0

我有这个查询

$query = "SELECT * FROM items WHERE itemStatus = '1' AND itemAdded > '$timestamp'";

一旦此查询返回结果,我将遍历结果

结果数组为 itemID、itemLocationID、categoryParentID、categoryID、itemName、itemDetails

在循环期间,我然后通过调用同一类中的函数来运行其他三个查询

$locationName = $this->getLocationByName($locationID);
$categoryParentName = $this->getCategoryByName($categoryParentID);
$categoryName = $this->getCategoryByName($categoryID);

函数 getLocationByName 执行此查询;

$q = mysql_query("SELECT * FROM locations WHERE locationID = '$locationID'");

这将返回一个包含 locationID、locationName、locationLink 的数组

函数 getCategoryByName 执行此查询;

$q = mysql_query("SELECT * FROM categories WHERE categoryID = '$categoryID'");

这将返回 categoryID、categoryName、categoryLink 的数组

有人可以帮我优化这个查询,也许加入他们以节省做这么多查询。

提前致谢。

我现在使用这个查询

$q = mysql_query("SELECT 
i.itemID, 
i.locationID,
i.categoryParentID,
i.categoryID, 
i.itemName,
i.itemDetails,
l.*,
c.*        

FROM items i 内部连接位置 l on i.locationID = l.locationID 内部连接类别 c on i.categoryID = c.categoryID WHERE itemStatus = '1' AND itemAdded > '$timestamp'") or die(mysql_error());

结果是

Array

( [itemID] => 81300 [locationID] => 17 [categoryParentID] => 21 [categoryID] => 183 [itemName] => blah [itemDetails] => blah [locationName] => 精彩,它按预期拉入位置. [locationLink] => blah [categoryName] => 精彩,它按预期拉入类别。[categoryLink] => blah )

[categoryName] => //these are missing for categoryParentID
[categoryLink] => //these are missing for categoryParentID
4

3 回答 3

1

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 ))
于 2013-02-19T16:06:33.690 回答
1

我不会在选择语句中使用 * 带有连接的查询可能是

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'

我希望它对你有用。干杯!

于 2013-02-19T16:08:40.170 回答
0

除非我遗漏了一些明显的东西,否则我可能会建议这样的事情作为第一个开始:

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'
于 2013-02-19T16:01:30.730 回答