如何执行有效的JOIN操作?

时间:2015-12-01 17:28:33

标签: php mysql join

我有一个包含以下数据的表:

tagmap

===============
 item | tagid
---------------
 1111 |   101
 1111 |   102
 2222 |   101
 2222 |   103
 3333 |   104
 4444 |   105
 4444 |   106
 5555 |   101
 5555 |   103
==============

item + tagid =复合主键

我有一个MySQL查询,如;

SELECT DISTINCT GROUP_CONCAT(a.tagid ORDER BY a.tagid) tags
  FROM tagmap a
  JOIN tagmap b
    ON b.item = a.item
   AND b.tagid <= a.tagid
 WHERE b.tagid = '101'
 GROUP
    BY a.item;

返回;

101,102
101,103

这些是101可用的唯一可能组合。

tagid是某些风格的独特ID。我还有另一张桌子;

风味

===============
 id  | flavor
---------------
 101 | flavorA
 102 | flavorB
 103 | flavorC
 104 | flavorD
 105 | flavorE
 106 | flavorF
===============

id =主键

而不是我以前的MySQL结果,我想要的是;

flavorA,flavorB
flavorA,flavorC

根据我的逻辑,我需要执行INNER JOIN。但是flavors表可能包含500K +条目,而tagmap表将至少比flavors表大2倍。因此,执行连接操作非常不容易。但我认为,如果我可以生成一个类似的表;

===============
 item | tagid
---------------
 1111 |   101
 1111 |   102
 2222 |   101
 2222 |   103
==============

然后我可以使用flavors表加入此表,这可能(我认为)比以前的连接操作更容易。我认为这可以通过嵌套查询来实现。

有什么方法可以实现这个目标吗? INNER JOIN是唯一可行的解​​决方案吗?如果是,那么我如何在查询中执行INNER JOIN?我使用PHP + MySQL。

2 个答案:

答案 0 :(得分:0)

我不明白为什么你需要自我加入。

您的第一个查询可以是

SELECT DISTINCT GROUP_CONCAT(a.tagid ORDER BY a.tagid) tags
  FROM tagmap a
 WHERE a.item IN (SELECT item from tagmap WHERE tagid = 101)
 GROUP BY a.item
HAVING COUNT(*) > 1

此查询和您的查询的复杂性可能大致相同。

一旦你有了这个工作,你可以非常简单地将风味名称替换为领带id值:

SELECT DISTINCT GROUP_CONCAT(b.flavor ORDER BY a.tagid) tags
  FROM tagmap a
  JOIN flavors b ON a.tagid = b.id
 WHERE a.item IN (SELECT item from tagmap WHERE tagid = 101)
 GROUP BY a.item
HAVING COUNT(*) > 1

我会为你准备一个SQLFiddle,但它现在不能正常工作。

JOININNER JOIN是一回事。)

答案 1 :(得分:0)

所以也许我错过了一些东西,但是这个查询不会给你你想要的结果吗?

SELECT tagmap.item, flavors.flavor
  FROM tagmap
  JOIN flavors
  ON tagmap.tagid = flavor.id;

这会将您的商品加入到每种风格中,其中tagid与风味ID匹配,结果为:

===============
 item | flavor
---------------
 1111 |   flavorA
 1111 |   flavorB
 2222 |   flavorA
 2222 |   flavorC
==============

使用此查询作为跳出点,您现在可以使用group_concat到期以格式化结果。或者,您可以通过在php中循环遍历结果。快速举例:

$my_array = [];
while ($data = $rows->fetch_assoc())
{
    //initalize the item if it doesn't exist yet
    if(!isset($my_array[$data['item']) {
        $my_array[$data['item']] = [];
    }
    //add the flavor to the time
    $my_array[$data['item'][] = $data['flavor'];
}

echo $json_encode($my_array);

结果:{1111:["flavorA", "flavorB"], 2222:...

希望有所帮助。