#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. Хорошее использование ракетостроения, хотя это просто проблема «перехода улицы».