powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Задача
11 сообщений из 11, страница 1 из 1
Задача
    #40136212
ucheniik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
На входе есть таблица с двумя полями
code_cat (int) – код запчасти
class_cat (varchar(1000)) – наименование
У одной запчасти может быть много вариантов наименований.
Нужно написать SQL запрос (желательно один), который удаляет из входной таблицы все избыточные строчки.
Избыточными считаются те, в которых все слова в описании запчасти присутствуют в другом описании этой же запчасти. В любом порядке.
Регистр не имеет значения, разделитель слов - пробел.

Можно написать вспомогательную функцию или использовать CTE.

Пример
code_cat class_cat
1 'Запчасть крыло левое'
1 'Запчасть крыло' -- избыточная запись
1 'Запчасть крыло Mazda'

2 'Фонарь правый Mazda 626'
2 'Фонарь' -- избыточная запись
2 'Фонарь Mazda фонарь правый' -- избыточная запись
2 'Запчасть'
2 'Запч Mazda'
2 'Фонарь правый Mazda 626' -- избыточная запись
2 ' 626 626 ' -- избыточная запись
...
Рейтинг: 0 / 0
Задача
    #40136213
Фотография HandKot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ucheniik, а Вы сами что успели сделать?
Или Вам надо сделать за Вас?
...
Рейтинг: 0 / 0
Задача
    #40136219
ucheniik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
HandKot, делал перебором, но много вложенных циклов получается.
...
Рейтинг: 0 / 0
Задача
    #40136228
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ucheniik,

не сказал бы, что это задача для начинающего. Для решения необходимо составить словарь всех слов, входящих с таблицу и установить связь каждой строки с этим словарём через промежуточную таблицу. Затем искать вхождение множеств элементов словаря для каждой из строк друг в друга. Удалять те строки, элементы словаря которой полностью входят в элементы словаря другой, при этом, если оба множества совпадают, должна остаться любая из этих строк.
По моему мнению, такую задачу лучше решать на каком-либо объектном языке.
...
Рейтинг: 0 / 0
Задача
    #40136259
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. разобрать строки на слова по разделителям. Результат - таблица, в которой одно слово занимает одну строку
и слова из одной исходной строки имеют один id этой исходной строки.
2. собрать исходные строки из полученных слов для каждого id, но в словарном порядке.
3. удалить из каждой группы с одинаковыми строками все строки, кроме одной.
...
Рейтинг: 0 / 0
Задача
    #40136447
ValK412
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iap
1. разобрать строки на слова по разделителям. Результат - таблица, в которой одно слово занимает одну строку
и слова из одной исходной строки имеют один id этой исходной строки.
2. собрать исходные строки из полученных слов для каждого id, но в словарном порядке.
3. удалить из каждой группы с одинаковыми строками все строки, кроме одной.

3.Сборка в словарном порядке не подойдет, как пример
Zapchast levoe krylo - упорядочено по алфавиту.
Zapchast krylo
сделал через преобразование словаря по каждой категории в битовую маску
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
--https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=1257ac4340dc150f01a7a5461896c95b
with src as (select * from (values 
 (1,1, 'Zapchast krylo levoe')
,(2,1, 'Zapchast krylo') -- избыточная запись
,(3,1, 'Zapchast krylo Mazda')
,(4,2, 'Fonar pravy Mazda 626')
,(5,2, 'Fonar') -- избыточная запись
,(6,2, 'Fonar Mazda fonar pravy') -- избыточная запись
,(7,2, 'Zapchast')
,(8,2, 'Zapch Mazda')
,(9,2, 'Fonar pravy Mazda 626') -- избыточная запись
,(10,2, ' 626 626 ') -- избыточная запись
,(11,2,'Tests')
 )as t(id_cat,code_cat, class_cat)
)
,rsplit as ( select id_cat,code_cat,trim(class_cat) as class_cat,len(trim(class_cat)) as l
    ,1 as p1 ,cast(charindex(' ',trim(class_cat)) as int) p2
    from src s
    union all 
    select r.id_cat,r.code_cat,r.class_cat,r.l
    ,r.p2+1 as p1  ,cast(charindex(' ',r.class_cat,r.p2+1) as int) p2
    from rsplit r 
    where r.p2>0
)
, allwords as (select id_cat,code_cat,class_cat,p1,p2,l ,substring(class_cat,p1,iif(p2>p1,p2-p1,l-p1+1)) as word
      from rsplit
)
, words as (select id_cat,code_cat,class_cat,word from allwords 
            group by id_cat,code_cat,class_cat,word
)
, dict as(select code_cat,word,rank() over (partition by code_cat order by word) as rng 
          from(select code_cat,word from words group by code_cat,word)t
)
, rng as ( select w.id_cat,w.code_cat,w.class_cat,w.word, d.rng
         ,power(2,d.rng) as mask
        from words w left join dict d on d.code_cat=w.code_cat and d.word=w.word
)
,ord0 as ( select id_cat,code_cat,class_cat,sum_mask
             ,rank() over (partition by code_cat,sum_mask order by id_cat) as rnk
           from (select id_cat,code_cat,class_cat,sum(mask) as sum_mask --convert(binary(8),sum(mask),1) as sum_mask 
                  from rng   group by id_cat,code_cat,class_cat) t
)
,ord as ( select id_cat,code_cat,class_cat,sum_mask,rnk --convert(binary(8),sum_mask,1) as sum_mask 
                  from ord0 where rnk=1
)
,rep as ( select t1.id_cat,t1.code_cat,t1.class_cat,convert(binary(8),t1.sum_mask,1) as sum_mask
                ,convert(binary(8),((t2.sum_mask ^ t1.sum_mask) & t1.sum_mask),1) as NorAnd
      from ord t1 left join ord t2 on t2.code_cat=t1.code_cat 
          and t2.id_cat<>t1.id_cat
)
,repClr as ( select id_cat,code_cat,class_cat
     ,iif(min(NorAnd)>0,'','del') inlist
     from rep
     group by id_cat,code_cat,class_cat 
     --having min(NorAnd)>0
)
select * from repClr --rng --dict --rsplit
order by id_cat

...
Рейтинг: 0 / 0
Задача
    #40136509
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ValK412,

можно бы было написать так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
/*
drop table if exists #t;

create table #t (
id_cat int,
code_cat varchar(255),
class_cat varchar(255)
);


with src as (select * from (values 
 (1,1, 'Zapchast krylo levoe')
,(2,1, 'Zapchast krylo') -- избыточная запись
,(3,1, 'Zapchast krylo Mazda')
,(4,2, 'Fonar pravy Mazda 626')
,(5,2, 'Fonar') -- избыточная запись
,(6,2, 'Fonar Mazda fonar pravy') -- избыточная запись
,(7,2, 'Zapchast')
,(8,2, 'Zapch Mazda')
,(9,2, 'Fonar pravy Mazda 626') -- избыточная запись
,(10,2, ' 626 626 ') -- избыточная запись
,(11,2,'Tests')
 )as t(id_cat,code_cat, class_cat)
)
insert into #t select * from src;

*/
with wordlist as (
    select #t.[id_cat], #t.[code_cat], x.[value] as [word]
    from #t
        cross apply string_split([class_cat], char(32)) x
    where x.[value] > ''
)
select *
from #t t
where exists (
     select w1.[word] from wordlist w1 where w1.[id_cat] = t.[id_cat]
     except
     select w2.[word] from wordlist w2 where w2.[code_cat] = t.[code_cat] and w2.[id_cat] < t.[id_cat]
);



но здесь большую роль играет в каком порядке определять не избыточную запись, в выделеном фрагменте предикат мог быть > или <>
потому что в вашем варианте к примеру:

Код: sql
1.
2.
3.
,(4,2, 'Fonar pravy Mazda 626')
,(6,2, 'Fonar Mazda fonar pravy') -- избыточная запись
,(9,2, 'Fonar pravy Mazda 626') -- избыточная запись


избыточными являются строки с id_cat {6,9}, хотя 4 и 9 равноценны и могла бы оставаться 9
...
Рейтинг: 0 / 0
Задача
    #40136528
ValK412
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
felix_ff
ValK412,

можно бы было написать так:
Код: sql
1.
2.
3.
4.
5.
6.
with wordlist as (
    select #t.[id_cat], #t.[code_cat], x.[value] as [word]
    from #t
        cross apply string_split([class_cat], char(32)) x
    where x.[value] > ''
)


Спасибо за пример! Насколько изящнее решение через cross apply!
В целом мой пример оказался слишком школьным. Видимо, сильно влияние "обычных" языков программирования)
Решение
Код: sql
1.
2.
3.
4.
5.
6.
7.
select *
from #t t
where exists (
     select w1.[word] from wordlist w1 where w1.[id_cat] = t.[id_cat]
     except
     select w2.[word] from wordlist w2 where w2.[code_cat] = t.[code_cat] and w2.[id_cat] < t.[id_cat]
);

с несколько измененными входными данными
Код: sql
1.
2.
3.
4.
5.
 (1,1, 'Zapchast krylo levoe')
,(12,1, 'Zapchast koleso pravoe')
,(2,1, 'Zapchast krylo') -- избыточная запись
,(3,1, 'Zapchast krylo Mazda')
,(13,1, 'Zapchast koleso levoe Mazda')

исключит вариант
Код: sql
1.
,(13,1, 'Zapchast koleso levoe Mazda')

как избыточный, поскольку все слова из п.13 есть в других пунктах, но в других комбинациях.
Думаю, это не верно.
...
Рейтинг: 0 / 0
Задача
    #40136537
ValK412
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
проверку уникальности фразы сделать примерно так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with wordlist as (
    select #t.[id_cat], #t.[code_cat], x.[value] as [word]
    from #t
        cross apply string_split([class_cat], char(32)) x
    where x.[value] > ''
)
, cat as (
select t.* ,(
    select top 1 id_cat  from #t t2 
     where t2.[code_cat] = t.[code_cat] and t2.id_cat<>t.id_cat
     and not exists (
        select  w1.[word] word from wordlist w1 where w1.[id_cat] = t.[id_cat]
        except
        select w2.[word] from wordlist w2 
           where w2.[code_cat] = t.[code_cat] and w2.[id_cat] = t2.[id_cat]
         )   
     ) as id_cat2
from #t t
)
select * from cat
where (id_cat2 is null) or id_cat2>id_cat
order by code_cat,id_cat
;
...
Рейтинг: 0 / 0
Задача
    #40136628
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТС ждёт решения, надо как-то интенсивнее за него сделать всё, чтобы он ка не понимает, так и не понял, что это и куда
...
Рейтинг: 0 / 0
Задача
    #40136630
ValK412
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ролг Хупин
ТС ждёт решения, надо как-то интенсивнее за него сделать всё, чтобы он ка не понимает, так и не понял, что это и куда
Однако, это проблема ТС)
Задача мне показалась интересной. Примеры - полезные.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Задача
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]