Разделите списки на отдельные элементы и работайте на этом уровне.
Некоторые таблицы:
списки
- ID (PK)
- последовательность (записи "A-B-C-D" выше)
- [что-нибудь еще]
товар
- ID (PK)
- имя (значение, слово, все, что имеет смысл)
- [что-нибудь еще]
list_items
- LIST_ID
- ITEM_ID
- [порядковый номер int, если «G-H-B-A» и «A-B-G-H» считаются разными последовательностями]
(составной PK list_ID, item_ID [, порядковый номер] для этого, базовое отношение многие: многие)
Некоторые данные, поэтому более ясно, что представляют таблицы:
INSERT INTO items (ID, name) VALUES (1, 'A'), (2, 'B'), (3, 'G'), (4, 'H');
INSERT INTO lists (ID, sequence) VALUES (1, 'A-B-G-H');
INSERT INTO list_items (list_ID, item_ID) VALUES (1, 1), (1, 2), (1, 3), (1, 4);
INSERT INTO lists (ID, sequence) VALUES (2, 'B-A-G');
INSERT INTO list_items (list_ID, item_ID) VALUES (2, 2), (2, 1), (2, 3);
И, наконец, найти списки, которые содержат всех элементов (A, B, G, H):
SELECT lists.sequence FROM lists
JOIN list_items ON lists.ID = list_items.list_ID
JOIN items AS i1 ON list_items.item_ID = i1.ID HAVING i1.name = 'A'
JOIN items AS i2 ON list_items.item_ID = i2.ID HAVING i2.name = 'B'
JOIN items AS i3 ON list_items.item_ID = i3.ID HAVING i3.name = 'G'
JOIN items AS i4 ON list_items.item_ID = i4.ID HAVING i4.name = 'H'
Это должно вернуть любые списки, такие как «A-B-G-H», «G-H-A-B», «H-A-T-B-A-G» и т. Д., Но не «B-U-G-H-U-T» (нет A) или «B-A-T-H» (нет G) - все условия должны быть выполнены. Выполнение «любого» поиска может быть немного более сложным (написать это в моей голове за обедом, но RIGHT JOIN
может привести ко всем видам дубликатов и медлительности).
Он не будет отображать какие-либо геномы или переопределять человеческий язык, но должен подойти для набора данных приличного размера. В любом случае, я бы не стал хранить каждый список как varchar и делать "WHERE sequence LIKE '%A%' AND sequence LIKE '%B%'
", если только вы абсолютно не справитесь с дополнительной работой по добавлению новых данных.