我正在尝试从包含数字列表的mySQL表中提取特定行。
我有一个包含2列ID和数据的表格。每行都有一个排序的,用逗号分隔的数字记录,范围从1到1000。我只想选择其中包含部分或全部特定数字集的记录。我已经尝试过使用LIKE和IN,还查看了FIND_IN_SET。
t1.id t1.data
1 2,9,569
2 2,9,991,979
3 9,569,763
4 52,57,569,763,892,897
5 763
6 2,9,10,15,151,569,771,801,888,973
如果我要查找具有一个或多个值(2,9,569,763)的行,则无需编写:
SELECT t1.id from t1
WHERE t1.data NOT IN (1,3,4,5,6,7,8,10,11,...........,1000);
返回3行,t1.id = 1,3和5。
有没有更简单的方法?类似于(在mySQL中):
SELECT t1.id from t1
WHERE t1.data "only includes one or more of" (2,9,569,763);
答案 0 :(得分:1)
不简单,但是..
对单个匹配进行计数,并将其与data
列中所有值的数量进行比较。它们必须相等。
select id, data
from t1
where (find_in_set(2, data) > 0)
+ (find_in_set(9, data) > 0)
+ (find_in_set(569, data) > 0)
+ (find_in_set(763, data) > 0)
= char_length(data) - char_length(replace(data, ',', '')) + 1
答案 1 :(得分:1)
Paul Spiegel的答案给出了正确的结果,但是由于使用了FIND_IN_SET(),因此无法使用索引进行优化。它将始终进行表扫描,当您拥有更多的行时,它将变得越来越昂贵。
您应该以此为线索,当您实际上想对列表的离散成员进行一些搜索时,将数字列表作为逗号分隔的列表存储在字符串列中是个坏主意。
您应该做的是将列表存储为子表,每行一个成员。
CREATE TABLE mydata (
t1id INT NOT NULL,
member INT NOT NULL,
PRIMARY KEY (t1id, member),
FOREIGN KEY (t1id) REFERENCES t1(id)
);
INSERT INTO mydata VALUES
(1,2),(1,9),(1,569),
(2,2),(2,9),(2,991),(2,979),
(3,9),(3,569),(3,763),
(4,52,(4,57,(4,569,(4,763,(4,892),(4,897),
(5,763),
(6,2),(6,9),(6,10),(6,15),(6,151),(6,569),(6,771),(6,801),(6,888),(6,973);
现在,您将把原始表t1
联接到mydata
,但排除与所需列表中值匹配的项。
mysql> select * from t1 left join mydata on t1.id=mydata.t1id
and mydata.member not in (2,9,569,763);
+----+------+--------+
| id | t1id | member |
+----+------+--------+
| 1 | NULL | NULL |
| 2 | 2 | 979 |
| 2 | 2 | 991 |
| 3 | NULL | NULL |
| 4 | 4 | 52 |
| 4 | 4 | 57 |
| 4 | 4 | 892 |
| 4 | 4 | 897 |
| 5 | NULL | NULL |
| 6 | 6 | 10 |
| 6 | 6 | 15 |
| 6 | 6 | 151 |
| 6 | 6 | 771 |
| 6 | 6 | 801 |
| 6 | 6 | 888 |
| 6 | 6 | 973 |
+----+------+--------+
您会看到id为1、3、5的NULL,因为没有任何不在指定列表中的值。这些是您要返回的ID。
mysql> select t1.id from t1 left join mydata on t1.id=mydata.t1id
and mydata.member not in (2,9,569,763)
where mydata.member is null;
+----+
| id |
+----+
| 1 |
| 3 |
| 5 |
+----+
答案 2 :(得分:0)
尝试使用REGEXP函数:
SELECT t1.id from t1
WHERE t1.data REGEXP '(2,9,569,763)';