微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – 在MySQL中实现SQL INTERSECT时嵌套过高

我最后的作品之一是基于Yii的硬件目录.每个项目都可以与很多组链接.

@H_502_4@CREATE TABLE item_group ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, itemId INT(10) UNSIGNED NOT NULL, groupId INT(10) UNSIGNED NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

显示必须由用户选择的所有groupIds的itemIds.这是我的错误解决方案:

@H_502_4@$groups = isset($_GET['groups']) ? array_merge(array_diff($_GET['groups'], array('0'=>'-')),array()) : array(); $sql = ''; $brackets = ''; $groupMaxKey = count($groups) - 1; //some code here for($i=0;$i<=$groupMaxKey;$i++){ $sql .= "SELECT itemId FROM item_group WHERE groupId='".$groups[$i]."' "; if($i != $groupMaxKey){ $sql .= "AND itemId IN ("; $brackets .= ")"; } else { $sql .= $brackets; } }

我发现最大嵌套级别为32.更多组给出错误.什么是最干净的解决方案?

这里要澄清一个查询示例:

@H_502_4@SELECT itemId FROM item_group WHERE groupId='31' AND itemId IN ( SELECT itemId FROM item_group WHERE groupId='24' AND itemId IN ( SELECT itemId FROM item_group WHERE groupId='35' ) )

////
答案确实有效:

@H_502_4@SELECT g1.itemId FROM ((((((((((((((((((((((((((((((((((((((( item_group g1 INNER JOIN item_group g2 ON g1.itemId = g2.itemId) INNER JOIN item_group g3 ON g1.itemId = g3.itemId) INNER JOIN item_group g4 ON g1.itemId = g4.itemId) INNER JOIN item_group g5 ON g1.itemId = g5.itemId) INNER JOIN item_group g6 ON g1.itemId = g6.itemId) INNER JOIN item_group g7 ON g1.itemId = g7.itemId) INNER JOIN item_group g8 ON g1.itemId = g8.itemId) INNER JOIN item_group g9 ON g1.itemId = g9.itemId) INNER JOIN item_group g10 ON g1.itemId = g10.itemId) INNER JOIN item_group g11 ON g1.itemId = g11.itemId) INNER JOIN item_group g12 ON g1.itemId = g12.itemId) INNER JOIN item_group g13 ON g1.itemId = g13.itemId) INNER JOIN item_group g14 ON g1.itemId = g14.itemId) INNER JOIN item_group g15 ON g1.itemId = g15.itemId) INNER JOIN item_group g16 ON g1.itemId = g16.itemId) INNER JOIN item_group g17 ON g1.itemId = g17.itemId) INNER JOIN item_group g18 ON g1.itemId = g18.itemId) INNER JOIN item_group g19 ON g1.itemId = g19.itemId) INNER JOIN item_group g20 ON g1.itemId = g20.itemId) INNER JOIN item_group g21 ON g1.itemId = g21.itemId) INNER JOIN item_group g22 ON g1.itemId = g22.itemId) INNER JOIN item_group g23 ON g1.itemId = g23.itemId) INNER JOIN item_group g24 ON g1.itemId = g24.itemId) INNER JOIN item_group g25 ON g1.itemId = g25.itemId) INNER JOIN item_group g26 ON g1.itemId = g26.itemId) INNER JOIN item_group g27 ON g1.itemId = g27.itemId) INNER JOIN item_group g28 ON g1.itemId = g28.itemId) INNER JOIN item_group g29 ON g1.itemId = g29.itemId) INNER JOIN item_group g30 ON g1.itemId = g30.itemId) INNER JOIN item_group g31 ON g1.itemId = g31.itemId) INNER JOIN item_group g32 ON g1.itemId = g32.itemId) INNER JOIN item_group g33 ON g1.itemId = g33.itemId) INNER JOIN item_group g34 ON g1.itemId = g34.itemId) INNER JOIN item_group g35 ON g1.itemId = g35.itemId) INNER JOIN item_group g36 ON g1.itemId = g36.itemId) INNER JOIN item_group g37 ON g1.itemId = g37.itemId) INNER JOIN item_group g38 ON g1.itemId = g38.itemId) INNER JOIN item_group g39 ON g1.itemId = g39.itemId) INNER JOIN item_group g40 ON g1.itemId = g40.itemId) WHERE g1.groupId='1' AND g2.groupId='2' AND g3.groupId='3' AND g4.groupId='4' AND g5.groupId='5' AND g6.groupId='6' AND g7.groupId='7' AND g8.groupId='8' AND g9.groupId='9' AND g10.groupId='10' AND g11.groupId='11' AND g12.groupId='12' AND g13.groupId='13' AND g14.groupId='14' AND g15.groupId='15' AND g16.groupId='16' AND g17.groupId='17' AND g18.groupId='18' AND g19.groupId='19' AND g20.groupId='20' AND g21.groupId='21' AND g22.groupId='22' AND g23.groupId='23' AND g24.groupId='24' AND g25.groupId='25' AND g26.groupId='26' AND g27.groupId='27' AND g28.groupId='28' AND g29.groupId='29' AND g30.groupId='30' AND g31.groupId='31' AND g32.groupId='32' AND g33.groupId='33' AND g34.groupId='34' AND g35.groupId='35' AND g36.groupId='36' AND g37.groupId='37' AND g38.groupId='38' AND g39.groupId='39' AND g40.groupId='40'

解决方法:

您可以使用INNER JOIN来实现此目的.没有理由嵌套这些陈述.

对您的示例案例进行适当查询的任何示例都是:

@H_502_4@SELECT g1.itemId FROM (( item_group g1 INNER JOIN item_group g2 ON g1.itemId = g2.itemId) INNER JOIN item_group g3 ON g1.itemId = g3.itemId) WHERE g1.groupId='31' AND g2.groupId='24' AND g3.groupId='35'

我已经在一个包含三列(id,itemId,groupId)的简单表上测试了它,并且它可以工作.将这种语句放在循环中非常容易,并且连接数没有最大值.

要使此运行更快,您应该在item_group表中索引itemId列.

您可以使用以下sql语句执行此操作:

@H_502_4@ALTER TABLE item_group ADD INDEX ( itemId )

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐