我的数组值如下所示。
$findList = array(1,2,3,6);
我在数据库中有一个表格如下。
id sets
1 1
2 1,2
3 1,2,4
4 1,2,6
5 3,8,9
6 7,8,9
7 5,8,9
现在,我想找到所有具有任何数组findList的行。
因此结果集应该有前五行。
我可以通过爆炸数组和每个元素写OR查询来做到这一点。还有其他办法吗?
答案 0 :(得分:2)
依靠Lad2025的sqlfiddle以及来自Pavel的Clever Answer
CREATE TABLE tab(
id INTEGER NOT NULL PRIMARY KEY
,sets VARCHAR(6) NOT NULL
);
INSERT INTO tab(id,sets) VALUES (1,'1');
INSERT INTO tab(id,sets) VALUES (2,'1,2');
INSERT INTO tab(id,sets) VALUES (3,'1,2,4');
INSERT INTO tab(id,sets) VALUES (4,'1,2,6');
INSERT INTO tab(id,sets) VALUES (5,'3,8,9');
INSERT INTO tab(id,sets) VALUES (6,'7,8,9');
INSERT INTO tab(id,sets) VALUES (7,'5,8,9');
-- 1,2,3,6 ... seek this
select * from tab
WHERE CONCAT(",", `sets`, ",") REGEXP ",(1|2|3|6),";
+----+-------+
| id | sets |
+----+-------+
| 1 | 1 |
| 2 | 1,2 |
| 3 | 1,2,4 |
| 4 | 1,2,6 |
| 5 | 3,8,9 |
+----+-------+
更好的是,请参阅上面有关数据规范化的问题的评论。如果你这样做,你可能会选择最佳的索引使用。
答案 1 :(得分:0)
还有其他办法吗?
只是为了好玩,您可以像第一条评论一样使用IN
条款。此代码不应在生产环境中使用:)
SELECT *
FROM tab
WHERE id IN (SELECT id
FROM (
SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(t.sets, ',', n.n), ',', -1) AS val
FROM tab t
CROSS JOIN
(
SELECT a.N + b.N * 10 + 1 n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
) n
WHERE n.n <= 1 + (LENGTH(t.sets) - LENGTH(REPLACE(t.sets, ',', '')))
) sub
WHERE val IN (1,2,3,6)
)
的 SqlFiddleDemo
强>
输出:
╔═════╦═══════╗
║ id ║ sets ║
╠═════╬═══════╣
║ 1 ║ 1 ║
║ 2 ║ 1,2 ║
║ 3 ║ 1,2,4 ║
║ 4 ║ 1,2,6 ║
║ 5 ║ 3,8,9 ║
╚═════╩═══════╝