2014-10-14 5 views
2

У меня есть столбец categories в моей таблице company. В этом categories может быть так много категорий, разделенных ,. Что-то вроде 1,2,3,4,5, и я знаю одну из этой категории id.SQL-запрос с запятой колонкой

Скажем, 1 пока.

Так как я могу запросить company стол?

+1

Предполагая, что это поле персонажа, вы можете использовать оператор [LIKE] (http://www.w3schools.com/sql/sql_like.asp): 'где как '%, 1,%''. – Andrew

+4

Можете ли вы изменить структуру таблицы так, чтобы она имела строку для каждой категории? – Lamak

+0

@Lamak или еще лучше, добавьте новую таблицу, которая имеет строку для каждой связи между компаниями/категориями. –

ответ

0

Вы должны иметь дело с четыре случая: categories речи идет первым в список, внутренний список, последний в списке и только категории: SELECT * FROM company WHERE categories LIKE '1,%' OR categories LIKE '%,1,%' OR categories LIKE '%,1' OR categories='1'.

+2

Так как вы все равно собираетесь сканировать, почему бы не упростить? 'WHERE ',' + categories + ',' LIKE '%, 1,%';'? –

+0

Мне это нравится. Является ли это проще или не зависит от POV. Если хорошо понимать SQL, он немного компактнее. Если нет, то, вероятно, менее понятно, почему эта версия работает. Я также думаю, что это почти наверняка, производительность является как «большой-O», так и практически эквивалентной. – zanerock

0

Вы можете сделать:

SELECT * 
FROM company 
WHERE (categories like '%,categoryId,%' or categories like 'categoryId,%') 

Вторым, как п заботится о вашей первой записи, которая не имеет предшествующей кома

+0

как насчет последнего? –

+0

@SamIam Ха-ха сходить с ума и добавить такие категории, как «%, categoryId» – 6ton

+1

Это неверно. он пропускает, когда рассматриваемый categoryId является последним и единственным вариантом в списке. – zanerock

0

PostgreSQL имеет arrays и array functions, которые позволяют вам решить эту проблему аккуратно.

Предположим следующую схему и образец данных:

CREATE TABLE company 
    ("name" varchar(13), "categories" varchar(9)); 

INSERT INTO company 
    ("name", "categories") 

VALUES 
    ('acme', '1,2,3,4,5'), 
    ('abc', '2,3,4'), 
    ('xyz', '3,5'), 
    ('stackoverflow', '4'); 

Затем вы можете использовать любой оператор, чтобы найти элемент в массиве, как так:

SELECT 
    name 

FROM (
    SELECT NAME, string_to_array(categories, ',') AS category_array FROM company 
    ) n 

WHERE 
    '2' = ANY (category_array); 

Который должен вернуться acme и abc, согласно this SQLFiddle.

+0

Это также намного больше возможностей и гибкости в том, что вы можете запрашивать несколько категорий с такими вещами, как 'ARRAY ['2', '4'] <@ category_array', который проверяет, содержится ли' 2,4' в любой категории, возвращая 'acme' и' abc'. См. Пример на http://sqlfiddle.com/#!15/bd4e2/1 –

Смежные вопросы