Как получить число, в котором есть «/»

#sql #sql-server

#sql #sql-сервер

Вопрос:

Я пишу sql-запрос для извлечения значения из термина столбца, который находится в таблице alpha, в котором есть «/». У меня есть такие значения, как:

 300/500/100
25/50/15
300/500
100/300
25/50/15
100/300
25000/50000
100/300
100/300
25/50/15
100/300/100
300/500/100
300/500/300
25/50/15
25000/50000
100/300
  

Вывод должен быть

 300/500
100/300
100/300
100/300
25000/50000
  

Оно не должно включать в себя число, в котором есть двойное «/».

Я пытаюсь использовать следующий запрос для извлечения точного результата

Мой подход 1:

 Select term from alpha where 
term like '%[0-9]/[0-9]%'
  

мой подход 2

 Select term from alpha where    (CASE 
        WHEN term Like '%/%' THEN Left(term, CHARINDEX('/', term)-1)
        Else term
        End 
  

Но я не получаю точного результата при выполнении подхода 1. Я получаю ошибку в подходе 2. Пожалуйста, помогите мне разобраться в проблеме

Комментарии:

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

2. @SeanLange: вы также можете поместить .mdf файл в VARBINARY(max) столбец.

3. @Joshua Я не понимаю контекста. Не уверен, какое отношение к этому вопросу имеет помещение файла mdf в varbinary (max).

4. Объясните свою логику. У вас есть 5 экземпляров «100/300», но ваши ожидаемые результаты имеют 3 экземпляра.

5. OP — вы должны закрыть свой вопрос, отметив ответ как принятый. Похоже, у Gen Wan элегантный запрос.

Ответ №1:

Попробуйте это:

 select term from alpha 
where term like '%/%' -- >= one '/'
and term not like '%/%/%' -- < two '/'
  

Комментарии:

1. Мне нравится этот SQL. Красиво и лаконично.

Ответ №2:

Подобно другим подходам, этот подход просто получает термин, который имеет как минимум 1 / , а затем дополнительно ограничивает результаты тем, у которого нет 2 / .

Смотрите Пример здесь: https://rextester.com/LQI52271

 create table alpha (
    term varchar(100)
);

insert into alpha values
('300/500/100')
,('25/50/15')
,('300/500')
,('100/300')
,('25/50/15')
,('100/300')
,('25000/50000')
,('100/300')
,('100/300')
,('25/50/15')
,('100/300/100')
,('300/500/100')
,('300/500/300')
,('25/50/15')
,('25000/50000')
,('100/300');

select term
from alpha
where term like '%/%'
    and len(REPLACE(term, '/', '')) = len(term) - 1
order by term;
  

ВЫВОД

Обратите внимание, что выходные данные отличаются от ваших. На вашем входе действительно есть 5 экземпляров 100/300.

     term
1   100/300
2   100/300
3   100/300
4   100/300
5   100/300
6   25000/50000
7   25000/50000
8   300/500
  

Ответ №3:

Один из возможных подходов — подсчитать количество / символов и выбрать только строки с числом, равным 1 :

Ввод

 CREATE TABLE #alpha (
   term varchar(50)
)
INSERT INTO #alpha
   (term)
VALUES
   ('300/500/100'),
   ('25/50/15'),
   ('300/500'),
   ('100/300'),
   ('25/50/15'),
   ('100/300'),
   ('25000/50000'),
   ('100/300'),
   ('100/300'),
   ('25/50/15'),
   ('100/300/100'),
   ('300/500/100'),
   ('300/500/300'),
   ('25/50/15'),
   ('25000/50000'),
   ('100/300')
  

Инструкция

 SELECT term 
FROM #alpha
WHERE 
   (term LIKE '%/%') AND
   (LEN(term) - LEN(REPLACE(term, '/', ''))) = 1 
  

Вывод

 --------------
term
--------------
300/500
100/300
100/300
25000/50000
100/300
100/300
25000/50000
100/300
  

Ответ №4:

Другой вариант (просто для развлечения) — использовать hierarchyid тип данных

Пример

  Select *
  From  alpha
  Where try_convert(hierarchyid,'/' term '/').GetLevel() = 2
  

Комментарии:

1. Хорошее использование ракетостроения, хотя это просто проблема «перехода улицы».