如何获取 4 个不同值的 ID(2 个键的组合)
How to get Ids of 4 distinct values ( combination of 2 keys )
我得到了 table 如下所示
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...)
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
子句中?
我需要这样的东西,因为我的 tb_dts
包含更多 3000 万 个 reocrds 和 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
select * from tb_dts where Id IN (20,21,22,13,14,15,16,23,24,25,26 )
这是我的table
的结构
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 个唯一值
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
我希望为 group by key1,key2 limit 0,4
得到这样的 Id
,以便可以在我的 WHERE IN
子句中使用它。
1
2
3
8
9
10
11
12
4
5
6
7
17
18
19
你的问题似乎有点令人困惑,但根据我的理解,如果你想要在 WHERE field IN clause
中使用 ID,你可以使用子查询。所以在你有 select key1,key2,group_concat(Id) from tb_dts group by key1,key2 limit 4,4;
的情况下,它可以简单地变成
select field
from table_name
where id IN
(select group_concat(Id)
from tb_dts group by key1,key2 limit 4,4)
您可以找到 google 个子查询以了解更多信息。让我知道您对这种方法的看法。希望这是一个步骤。
你可以试试这个
select *
from tb_dts
where Id IN (
SELECT r2.Ids from
( SELECT group_concat(Id) Ids
from tb_dts as r1
group by r1.key1,r1.key2
limit 4,4
) r2
);
对于您眼前的问题,您可以这样使用 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
);
您应该明白,group by 或 distinct 部分对性能的影响很大。如果有一个单独的 table 包含唯一的 key1,key2 并带有唯一索引,那就更好了。
create table the_keys_table(
key1 int not null,
key2 int not null,
primary key (key1, key2)
);
然后你可以将下面的 tb_dts 替换为 table,如下所示:
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
);
第 1 步:放弃您设想的分页方案。相反,在 key
上分页,而不是“每页 4 行”。
第 2 步:"Remember where you left off"。如果第一页包含 key1 = 1 或 2 的所有对,则第二页从 key1 = 2 之后的下一个值开始。
现在查询变得更加高效,因为它超过了 key1
个值的 "range" 个。目前,它必须在分页之前构建整个输出!
More 不使用分页的讨论 OFFSET
。
我得到了 table 如下所示
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...)
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
子句中?
我需要这样的东西,因为我的 tb_dts
包含更多 3000 万 个 reocrds 和 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
select * from tb_dts where Id IN (20,21,22,13,14,15,16,23,24,25,26 )
这是我的table
的结构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 个唯一值
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
我希望为 group by key1,key2 limit 0,4
得到这样的 Id
,以便可以在我的 WHERE IN
子句中使用它。
1
2
3
8
9
10
11
12
4
5
6
7
17
18
19
你的问题似乎有点令人困惑,但根据我的理解,如果你想要在 WHERE field IN clause
中使用 ID,你可以使用子查询。所以在你有 select key1,key2,group_concat(Id) from tb_dts group by key1,key2 limit 4,4;
的情况下,它可以简单地变成
select field
from table_name
where id IN
(select group_concat(Id)
from tb_dts group by key1,key2 limit 4,4)
您可以找到 google 个子查询以了解更多信息。让我知道您对这种方法的看法。希望这是一个步骤。
你可以试试这个
select *
from tb_dts
where Id IN (
SELECT r2.Ids from
( SELECT group_concat(Id) Ids
from tb_dts as r1
group by r1.key1,r1.key2
limit 4,4
) r2
);
对于您眼前的问题,您可以这样使用 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
);
您应该明白,group by 或 distinct 部分对性能的影响很大。如果有一个单独的 table 包含唯一的 key1,key2 并带有唯一索引,那就更好了。
create table the_keys_table(
key1 int not null,
key2 int not null,
primary key (key1, key2)
);
然后你可以将下面的 tb_dts 替换为 table,如下所示:
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
);
第 1 步:放弃您设想的分页方案。相反,在 key
上分页,而不是“每页 4 行”。
第 2 步:"Remember where you left off"。如果第一页包含 key1 = 1 或 2 的所有对,则第二页从 key1 = 2 之后的下一个值开始。
现在查询变得更加高效,因为它超过了 key1
个值的 "range" 个。目前,它必须在分页之前构建整个输出!
More 不使用分页的讨论 OFFSET
。