Intereting Posts

Как получить все строки, которые соответствуют по крайней мере одному значению из массива?

У меня есть значения в массиве, как показано ниже.

$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 запрос с каждым элементом. Есть ли другой путь?

Опираясь на sqlfiddle Lad2025 и этот Умный ответ от Павла

схема

 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 | +----+-------+ 

Еще лучше, см. Комментарии выше под вопросом для нормализации данных. Если вы это сделаете, вы можете выбрать оптимальное использование индексов.

Есть ли другой путь?

Просто для удовольствия вы можете использовать предложение IN как в первом комментарии. Этот код не должен использоваться в рабочей среде 🙂

 SELECT * FROM tab WHERE id IN (SELECT id FROM ( SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(t.sets, ',', nn), ',', -1) AS val FROM tab t CROSS JOIN ( SELECT aN + bN * 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 nn <= 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 ║ ╚═════╩═══════╝