我有下面的表
mysql> select * from tb_dts; +----+------+------+ | Id | key1 | key2 | +----+------+------+ | 1 | 1 | 1 | | 2 | 1 | 1 | | 3 | 1 | 1 | | 4 | 2 | 1 | | 5 | 2 | 1 | | 6 | 2 | 1 | | 7 | 2 | 1 | | 8 | 1 | 2 | | 9 | 1 | 2 | | 10 | 1 | 2 | | 11 | 1 | 2 | | 12 | 1 | 2 | | 13 | 3 | 1 | | 14 | 3 | 1 | | 15 | 3 | 1 | | 16 | 3 | 1 | | 17 | 2 | 2 | | 18 | 2 | 2 | | 19 | 2 | 2 | | 20 | 2 | 3 | | 21 | 2 | 3 | | 22 | 2 | 3 | | 23 | 3 | 2 | | 24 | 3 | 2 | | 25 | 3 | 2 | | 26 | 3 | 2 | +----+------+------+ 26 rows in set (0.00 sec)
我采用类似的值,在某些应用程序分页中使用
mysql> select distinct key1,key2 from tb_dts limit 0,4; +------+------+ | key1 | key2 | +------+------+ | 1 | 1 | | 1 | 2 | | 2 | 1 | | 2 | 2 | +------+------+ 4 rows in set (0.00 sec) mysql> select distinct key1,key2 from tb_dts limit 4,4; +------+------+ | key1 | key2 | +------+------+ | 2 | 3 | | 3 | 1 | | 3 | 2 | +------+------+ 3 rows in set (0.00 sec)
通过group_concat我也获得ID,但是,我想在WHERE Field IN子句中使用此ID,例如 where somefield IN ( ..here my Ids goes...)
group_concat
WHERE Field IN
where somefield IN ( ..here my Ids goes...)
mysql> select key1,key2,group_concat(Id) from tb_dts group by key1,key2 limit 0,4; +------+------+------------------+ | key1 | key2 | group_concat(Id) | +------+------+------------------+ | 1 | 1 | 1,2,3 | | 1 | 2 | 8,9,10,11,12 | | 2 | 1 | 4,5,6,7 | | 2 | 2 | 17,18,19 | +------+------+------------------+ 4 rows in set (0.00 sec) mysql> select key1,key2,group_concat(Id) from tb_dts group by key1,key2 limit 4,4; +------+------+------------------+ | key1 | key2 | group_concat(Id) | +------+------+------------------+ | 2 | 3 | 20,21,22 | | 3 | 1 | 13,14,15,16 | | 3 | 2 | 23,24,25,26 | +------+------+------------------+ 3 rows in set (0.00 sec)
但是,如何将其放在WHERE Fieldname IN子句中?
WHERE Fieldname IN
我需要这样的东西,因为我tb_dts包含超过 3000万个 记录,而15实际字段却无法使用ID BETWEEN min_id and max_id
tb_dts
15
ID BETWEEN min_id and max_id
为了处理前4个唯一组合值,我需要
select * from tb_dts where Id IN (1,2,3,8,9,10,11,12,4,5,6,7,17,18,19 )
为了处理接下来的4个唯一组合值,我需要在我的应用程序中使用ID,因此简而言之,我想在我的where Field IN子句中使用以下提到的ID
where Field IN
select * from tb_dts where Id IN (20,21,22,13,14,15,16,23,24,25,26 )
这是我桌子的结构
DROP TABLE IF EXISTS `tb_dts`; CREATE TABLE `tb_dts` ( `Id` int(11) NOT NULL AUTO_INCREMENT, `key1` int(11) DEFAULT '-99', `key2` int(11) DEFAULT '-99', PRIMARY KEY (`Id`), KEY `main` (`key1`,`key2`) ) ENGINE=MyISAM AUTO_INCREMENT=27 DEFAULT CHARSET=latin1; LOCK TABLES `tb_dts` WRITE; INSERT INTO `tb_dts` VALUES (1,1,1),(2,1,1),(3,1,1),(4,2,1),(5,2,1),(6,2,1),(7,2,1),(8,1,2),(9,1,2),(10,1,2),(11,1,2),(12,1,2),(13,3,1),(14,3,1),(15,3,1),(16,3,1),(17,2,2),(18,2,2),(19,2,2),(20,2,3),(21,2,3),(22,2,3),(23,3,2),(24,3,2),(25,3,2),(26,3,2); UNLOCK TABLES;
如您在此处看到的,它为每个不同的组合值提供了第一个找到的ID
mysql> select Id from tb_dts group by key1,key2 limit 0,4; +----+ | Id | +----+ | 1 | | 8 | | 4 | | 17 | +----+ 4 rows in set (0.00 sec)
但是我希望所有Ids这些都在给定的标准之内,那不过是所有ID都低于4个唯一值而已
Ids
mysql> select key1,key2 from tb_dts group by key1,key2 limit 0,4; +------+------+ | key1 | key2 | +------+------+ | 1 | 1 | --- 1,2,3 | 1 | 2 | --- 8,9,10,11,12 | 2 | 1 | --- 4,5,6,7 | 2 | 2 | --- 17,18,19 +------+------+ 4 rows in set (0.00 sec)
预期的o / p
我希望得到Id这样的group by key1,key2 limit 0,4,以便可以在我的WHERE IN子句中使用它。
Id
group by key1,key2 limit 0,4
WHERE IN
1 2 3 8 9 10 11 12 4 5 6 7 17 18 19
对于您眼前的问题,可以这样使用find_in_set:
find_in_set
select t.* from your_table t where exists ( select 1 from ( select group_concat(Id) from tb_dts group by key1, key2 order by key1, key2 -- very important when using limit limit 0, 4 ) t2 where find_in_set(t.fieldname, t2.ids) > 0 );
尽管我不确定这是否是做您正在做的事情的最佳方法。使用group by创建字符串,然后在该字符串中搜索将太慢。
另外,您还希望在key1,key2,id列上有一个索引。
create index idx_tb_dts on tb_dts (key1, key2, id);
可以尝试一下:
select t.* from your_table t where exists ( select 1 from tb_dts t1 inner join ( select distinct key1, key2 from tb_dts order by key1, key2 limit 0, 4 ) t2 on t1.key1 = t2.key1 and t1.key2 = t2.key2 where t1.id = t.fieldname );
您应该了解,分组或不同的部分可能会影响性能。如果有一个单独的表包含唯一的key1,key2并在其上具有唯一的索引,那就更好了。
create table the_keys_table( key1 int not null, key2 int not null, primary key (key1, key2) );
然后,您可以将下面的tb_dts替换为该表,如下所示:
select key1, key2 -- no distinct or group by needed. from the_keys_table order by key1, key2 limit 0, 4
您的最终查询将变为:
select t.* from your_table t where exists ( select 1 from tb_dts t2 where (key1, key2) in ( select key1, key2 from the_keys_table order by key1, key2 limit 0, 4 ) and t1.id = t.fieldname );