powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Как обойтись малой кровью?
21 сообщений из 21, страница 1 из 1
Как обойтись малой кровью?
    #37621686
Hunterex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Помогите, пожалуйста решить задачу
малыми ресурсами и временем
задача:

1) Есть таблица следующей структуры

code varchar(255)
group int

например:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
code1     1
code2     1
code3     1

code4     2
code5     2


code6     3
code7     3
code8     3



2) есть входные данные

code4, code5 и новый code9,

Надо:

добавить code9 в гр., которая заранее не известна.
Ее нужно определить по code4 и code5
иными словами
как мне отсеять code4 и code5 и добавить code9 в группу в которой уже находятся code4 и code5?


Задача реальная, не учебная.
Спасибо всем, кто поможет.
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37621744
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hunterex,
1) В чём кокретно проблема?
2) Если задача реальная - какая СУБД?
3) Какие ограничения: SQL, StoProc, одним выражением, на входе три параметра или таблица (строк всегла 3)?
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37621894
Hunterex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Проблема в том, что приложение критично к времени выполнения.
Надо как можно изящнее обновлять группы.
СУБД - MSSQL, количество строк 5-10 миллионов, в группе количество членов неограниченно, но всегда >1
не хочется делать много выборок для определения того что кода нет в базе и выяснения группы куда его определить
Ограничений особых нет. В основном время. Обновление группы будет проходить в отдельном треде, но тредов может быть много, поэтому от скорости будет так же зависеть и объем сжираемой памяти.
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37621946
JoFan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hunterex,

а если на входе будет: code4 code4 code9
куда надо добавить code9 ?
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37621953
Hunterex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добавляется только code9 в группу где находится code4
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37622004
JoFan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hunterex,

извиняюсь - скопипастил криво )

надо так:
а если на входе будет: code4 code6 code9
куда надо добавить code9 ?
т.е. в две группы добавить?
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37622024
Hunterex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет. Так не будет. Будут приходить только коды, которые принадлежат одной группе. Просто со временем могут появляться в этой группе новые коды, которых нет в базе.
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37622071
JoFan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
HunterexНет. Так не будет. Будут приходить только коды, которые принадлежат одной группе.

тогда зачем 2 кода, почему одним не обойтись ?
т.е. например "code5 и новый code9"

HunterexПросто со временем могут появляться в этой группе новые коды, которых нет в базе.

в какой "этой" ?

поле "code" уникально?
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37622150
Злой Бобр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hunterex,

Фиг поймешь че вам нада. Научитесь сначала внятно описывать условия. )))
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37622482
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Вы не ответили, в каком виде приходят входные данные, таки "пакетами" в виде табличек, где в каждом пакете члены только одной группы? При этом номер группы в пакете неизвестен и этот номер становится известен только в БД?
2. Вопрос практический, поэтому лучше сразу топик переносите в МS SQL...
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37622882
SERG1257
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Злой Бобр Фиг поймешь че вам нада. Научитесь сначала внятно описывать условия+1
Hunterex добавить code9добавить запись?
Hunterex в гр., которая заранее не известна.определить группу по входным параметрам?
Hunterex как мне отсеять code4 и code5 и добавить code9 в группу в которой уже находятся code4 и code5?Кроме вас на этот вопрос никто не ответит.
Hunterex Надо как можно изящнее обновлять группы.Стоп-стоп-стоп, выше вы хотели добавлять запись?
Hunterex количество строк 5-10 миллионовВ какой таблице?
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37622996
Hunterex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще раз.

Например, сегодня на мой запрос веб-сервис отдает мне массив из 3-кодов. Это коды деталей. Они взаимозаменяемы. Только производители разные.

Я проверяю по базе. Их там нет.

Записываю эту группу кодов в таблицу, присваиваю им какой-то там №. И продолжаю себе работать.

Но у моего поставщика через несколько дней вдруг появились на складе детали от нового производителя,
которые тоже могут заменить те детали из группы, которую я создал (см. выше).
Теперь мне надо пополнить Этими новыми кодами ту группу деталей, которая уже есть в базе. Т.е., используя, терминалогию описанную выше к кодам code4 и code5 добавить новый code9. Т.е. пополнить группу 2. Вот и вся задача. Что тут не понятного?
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37623082
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hunterex, ещё раз:
1. А может тебе завтра веб-сервис вернуть массив из 4-кодов?
2. Тебе только добавлять новые? А если группа была code2,code3,code4 а тебе серви вернул code2,code4,code5, что делать с code3?

телепат switched ON:

Код: 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.
PSEUDO-PL-SQL:

-- таблица с ранее сохранёнными группами

CREATE TABLE codes(
  code char NOT NULL, 
  inner_group integer NOT NULL
);

-- входная таблица с взаимозаменяемыми деталями
CREATE TEMP TABLE input_codes(
  id_input_code autoincrement, 
  code char NOT NULL,
  inner_group integer NULL
);

...
  -- находим номер группы
    SELECT min(inner_group)
             , max(inner_group)
           INTO v_mn
                 , v_mx
       FROM codes
           INNER JOIN input_codes 
               ON codes.code = input_codes.code;

  -- защита от дурака
   IF v_mn <> v_mx THEN
     RAISE EXCEPTION 'Входные данные не хотят подчиняться логике Hunterexa';
   END IF;

  -- раз уж MS SQL и версия неизвестна :)

  MERGE codes 
    USING  input_codes
       ON (input_codes.code = codes.code) AND (v_mn = codes.inner_group)
    WHEN NOT MATCHED BY TARGET 
      THEN INSERT (code, inner_group)
	    VALUES (source.code, v_mn);
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37623096
SERG1257
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
create table mytable (code varchar(255) primary key, grp_id int references groups, other_data varchar(255))
CREATE NONCLUSTERED INDEX idx_grp_id ON mytable(grp_id)



То бишь у вас две принципиально разные вставки - добавить группу и пополнить группу
для второго случая - вставить code9 c группой как у code4 (code5 здесь лишний и что делать если он по ошибке имеет не ту же самую группу как code4)

Код: sql
1.
2.
insert into mytable (code,grp_id)
select @code9,(select grp_id from mytable a where code=@code4)



Чем вас не устраивает подход "в лоб"?
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37623122
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SERG1257, insert требует прдварительной проверки на отстуствие. Либюо перехвата exeption :)
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37623945
Hunterex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Немного не так.

получаемые мною коды - всегда принадлежат одной группе.
Если группы нет - создать ее и добавить туда все коды.
Если группа есть - добавить туда только новые коды, которых там нет.

Из группы коды никогда не удаляются! Только пополнение.
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37623966
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
телепат switched ON 2:

Код: 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.
PSEUDO-PL-SQL:

-- таблица с ранее сохранёнными группами

CREATE TABLE codes(
  code char NOT NULL, 
  inner_group integer NOT NULL
);

-- входная таблица с взаимозаменяемыми деталями
CREATE TEMP TABLE input_codes(
  id_input_code autoincrement, 
  code char NOT NULL,
  inner_group integer NULL
);

...
  -- вдруг группа новая и select не найдёт ни одной строки
  SET v_mn = NULL;
  SET v_mx = NULL;

  -- пытаемся найти номер группы
    SELECT min(inner_group)
             , max(inner_group)
           INTO v_mn
                 , v_mx
       FROM codes
           INNER JOIN input_codes 
               ON codes.code = input_codes.code;

  -- защита от дурака
 
   IF ISNULL(v_mn, -1) <> ISNULL(v_mx, -1) THEN

     RAISE EXCEPTION 'Входные данные не хотят подчиняться логике Hunterexa';
   END IF;

 -- если таки группа новая - инициализируем новый ид для группы
  SET v_mn = ISNULL(v_mn, seq_innner_group.nextval());

  -- раз уж MS SQL и версия неизвестна :)
  MERGE codes 
    USING  input_codes
       ON (input_codes.code = codes.code) AND (v_mn = codes.inner_group)
    WHEN NOT MATCHED BY TARGET 
      THEN INSERT (code, inner_group)
	    VALUES (source.code, v_mn);



П.С.: Hunterex, Вы лентяй!
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37623996
Злой Бобр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hunterex,

Приведи пример в каком виде у тебя массив приходит. XML или что там у тебя?
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37624947
Hunterex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Данные приходят в виде массива

array[1].code
array[1].manufacturer

array[2].code
array[2].manufacturer

и т.д.

Я понимаю задача сложна для понимания но мне приходится ее решать.

Заметтье, группа не присутствует! Подразумевается, что детали принадлежат одной группе (ну по другому сказать это как синонимы в языке. Слова разные, а смысл один) , но новой или уже имеющейся надо определять каждый раз.

В этом массиве могут быть как коды уже ранее встречавшиеся и занесенные в базу, так и наряду с ними новые, которыми надо пополнить имеющуюся группу.
автор
Код: sql
1.
2.
 MERGE codes 
    USING ...



можно было бы использовать если бы обе таблицы имели бы № группы, а он у меня есть только в одной.
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37624971
SERG1257
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
create table mytable (code varchar(255) primary key, grp_id int references groups, other_data varchar(255))
CREATE NONCLUSTERED INDEX idx_grp_id ON mytable(grp_id)

create table #temp_codes_to_insert (code varchar(255) primary key)
--Заполняете вашу таблицу с порцией кодов
insert into #temp_codes_to_insert values (code4)
insert into #temp_codes_to_insert values (code5)
insert into #temp_codes_to_insert values (code9)

-- собственно вставка
declare @max_grp_id int
declare @min_grp_id int
declare @cnt int
declare @grp_id int

select
  @max_grp_id=max(grp_id),
  @min_grp_id min(grp_id),
  @cnt=count(*)
from mytable m join #temp_codes_to_insert i on i.code=m.code

if @cnt=0 
begin
 -- вставляете новую группу получаете ее grp_id
 set @grp_id=ident_current('groups')
end
else -- группа уже есть
begin
  if @max_grp_id<>@min_grp_id  -- не все коды принадлежат одной группе
    RAISERROR('не все коды принадлежат одной группе', 16, 1)
  else set @grp_id=@min_grp_id -- или @grp_id=@max_grp_id непринципиально
end

-- собственно вставка
insert into mytable (code,grp_id)
select code,@grp_id
from #temp_codes_to_insert i
where not exists (select * from mytable m where m.code=i.code)
...
Рейтинг: 0 / 0
Как обойтись малой кровью?
    #37624979
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
это всё я уже писал - ТС не читатель...

вот это
SERG1257
Код: sql
1.
2.
3.
4.
5.
  -- собственно вставка
  insert into mytable (code,grp_id)  
  select code,@grp_id
  from #temp_codes_to_insert i
  where not exists (select * from mytable m where m.code=i.code)


можно поменять на

Код: sql
1.
2.
3.
4.
5.
6.
  MERGE mytable o 
    USING  #temp_codes_to_insert AS i
       ON (i.code = o.code) -- можно даже без AND (o.inner_group = @grp_id )
    WHEN NOT MATCHED BY TARGET 
      THEN INSERT (code, inner_group)
	    VALUES (i.code, @grp_id);
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Как обойтись малой кровью?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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