2013-08-07 2 views
-1

В собственности mgt system я экономлю покупателей на основе их предпочтений. Скажите, что человек заинтересован в домах, у которых более 2 & меньше 4. Так что я сохранил его как 2,3,4. Пожалуйста, посмотрите приложение.Поиск разделенных запятыми строк в столбце t-sql

При поиске, скажите, что кто-то ищет покупателей, которые интересуются домами, которые имеют более 2, как я должен написать инструкцию select, чтобы проверить колонку спальни.

Если кто-то ищет покупателей, которые интересуются домами, которые имеют более 2 ванных комнат; что может быть выбранным заявлением?

enter image description here

+0

Не могли бы вы подробнее рассказать? Каков допустимый формат в области ванной комнаты/спальни? У вас есть «-3», чтобы указать «меньше 3». В чем разница между «1,2,3+» и «1+» ?. – thepirat000

+2

странный дизайн стола –

+0

Если это 1, значит, ему нужен только один. Если это плюс, ему может понравиться более 1 – Aruna

ответ

1

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

Прежде всего, давайте придумаем некоторые базовые правила. Если какая-либо из них нарушена, то окончательный ответ будет нуждаться в модификации (и, вероятно, будет более сложным).

  1. Если строка содержит + в любом месте, максимум - бесконечность.
  2. + может встречаться только в конце строки.
  3. Список всегда будет целым числом, разделенным запятой.
  4. Наименьшее число всегда будет первым в списке.
  5. Наибольшее число из которых всегда будет оставаться в списке.

Если все это правда, то после много работы я думаю, что у меня есть то, что вы можете использовать. Основная идея заключалась в том, чтобы придумать пару функций, которые будут получать значения min/max из ваших строк. После выполнения этих функций вы можете использовать их в статьях WHERE.

Для этого начинаются SQL Fiddle. Определения функций слева, пример запроса, чтобы дать вам суть того, как они работают справа.

CREATE FUNCTION dbo.list_min(@list_str AS VARCHAR(MAX)) 
    RETURNS INT 
    WITH RETURNS NULL ON NULL INPUT 
    AS BEGIN 
    DECLARE @comma_index INT; 
    SET @comma_index = CHARINDEX(',', @list_str); 
    DECLARE @result INT; 
    IF (0 < @comma_index) 
     SET @result = CONVERT(INT, LEFT(@list_str, @comma_index - 1)); 
    ELSE 
     SET @result = CONVERT(INT, REPLACE(@list_str, '+', '')); 
    RETURN @result; 
    END; 

и

CREATE FUNCTION dbo.list_max(@list_str AS VARCHAR(MAX)) 
    RETURNS INT 
    WITH RETURNS NULL ON NULL INPUT 
    AS BEGIN 
    IF (@list_str LIKE '%+') 
     RETURN 2147483647; -- Max INT 
    DECLARE @comma_index INT; 
    SET @comma_index = CHARINDEX(',', REVERSE(@list_str)); 
    DECLARE @result INT; 
    IF (0 < @comma_index) 
     SET @result = CONVERT(INT, RIGHT(@list_str, @comma_index - 1)); 
    ELSE 
     SET @result = CONVERT(INT, @list_str); 
    RETURN @result; 
    END; 

(Если кто-то может придумать способ, чтобы избавиться от этой нелепой result переменной, пожалуйста дайте мне знать. Я получаю ошибки о последнем заявлении «должно быть return return "при возврате внутри IF/ELSE, и я не смог получить синтаксис CASE.)

С этим в руке, вы можете делать запросы, как это:

SELECT * 
FROM stuff 
WHERE dbo.list_min(carspace) <= 2 AND 2 <= dbo.list_max(carspace) 

, который будет только выбрать свой второй ряд. (SQL Fiddle этого запроса.)

Третья функция, которую вы можете найти полезной, - это та, которая дает вам максимум в списке, но игнорирует +. Для этого это, по сути, функция list_max, но без блока IF, который проверяет наличие +. Получив эту функциональность, вы можете просто удалить + с list_max и создать еще одну функцию, которая проверяет наличие + и звонит list_max, если нет +.

Я не уверен в характеристиках производительности здесь. Я думаю, они невелики. Возможно, вы захотите рассмотреть некоторые индексирования на основе функций, если у вас есть большой объем данных для поиска.

Удачи. Надеюсь это поможет.

+0

Это было потрясающе. Спасибо за ваши усилия. Как вы уже упоминали, эти правила уже существуют. До сих пор он отлично работает. Вы много времени спасли ... :) – Aruna

1

Не было бы больше смысла хранить мин и макс, а затем запрос с <= и >=?

+0

да, это возможно. но дело в том, что ранее была построена структура таблицы. Если я изменю это, он сломает большинство мест :( – Aruna

+1

@aruna Возможно, было бы лучше повторить это сейчас, чем бороться с плохим дизайном, пока не придет королевство :-) –

0

Ваш дизайн стола не является оптимальным. Вы можете просто сохранить количество спален как целое. Вместо «1,2,3,4» вы будете смотреть только на 4 в этом случае.

Для ответа на конкретный вопрос, хотя, вы можете сделать заменить трюк, чтобы подсчитать количество запятых в колонке, как например:

SELECT * FROM myTable WHERE LEN(col) - LEN(REPLACE(col, ',','')) >= someNumber