简体   繁体   English

在MySQL Query中加入表而不是多个查询

[英]Joining Tables in MySQL Query instead of multiple queries

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 结果数组是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; 函数getLocationByName执行此查询;

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

this returns an array of locationID, locationName, locationLink 这将返回locationID,locationName,locationLink的数组

the function getCategoryByName performs this query; 函数getCategoryByName执行此查询;

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

this returns an array of categoryID, categoryName, categoryLink 这将返回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()); FROM项目i内部联接位置l on i.locationID = l.locationID内部联接类别c on i.categoryID = c.categoryID WHERE itemStatus ='1'AND itemAdded>'$ timestamp'“)或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 ) ([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

I think should be something similar to below query. 我认为应该类似于下面的查询。 I do not see where are you using $categoryParentName . 我没看到你在哪里使用$ 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. 使用categoryParentID更新查询 - 我不是说效率很高,但您可以根据需要进行测试和优化。

One option is to update above query - not sure that will work - and for large result sets using OR is not efficient: 一种选择是更新上面的查询 - 不确定是否有效 - 对于使用OR的大型结果集效率不高:

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. 我看到的另一个选项是获得2个结果集(见下文) - 一个用于categId = categId,第二个用于categId = categParentId,并将结果集合并在一个大结果集中。

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. 其他想法 - 未测试并假设id为int - 将必须转换为字符串/ 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. 如何编写此查询有几个选项 - 如果您发布结构表和一些虚拟数据,我相信有人会创建一个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语句中使用*带有连接的查询可能是

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'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM