|
Удаление дубликатов из ТаблицыЗначений | ☑ | ||
---|---|---|---|---|
0
Rounder
11.04.13
✎
13:09
|
Есть таблица значений ТЗ1 на 150К записей.
Есть в ней колонка "Ключ". Задача: оставить в таблице только по одной записи на "ключ". Причем если на ключ есть несколько записей - то нужно оставить последнюю. Реализовал так: создал ТЗ2 - пустая ТЗ со структурой ТЗ1. Иду циклом по ТЗ1 с конца к началу. На каждой итерации с помощью ТЗ2.Найти() ищу есть ли в ней уже такой ключ, если нету - добавляю запись, если есть - прохожу мимо. ИсходноеКоличество = ТЗ1.Количество(); Для Сч = 0 По ИсходноеКоличество - 1 Цикл НайденКлюч = ТЗ2.Найти(ТЗ1[ИсходноеКоличество - Сч - 1].Ключ, "Ключ"); Если НайденКлюч = Неопределено Тогда НоваяСтр = ТЗ2.Вставить(0); НоваяСтр.Ключ = ТЗ1[ИсходноеКоличество - Сч - 1].Ключ; КонецЕсли; КонецЦикла; Можно ли оптимальней сделать? Долго отрабатывает. |
|||
1
Ursus maritimus
11.04.13
✎
13:10
|
Можно
|
|||
2
Rounder
11.04.13
✎
13:11
|
Как?
|
|||
3
acsent
11.04.13
✎
13:12
|
сортировка и обход
|
|||
4
eklmn
гуру
11.04.13
✎
13:13
|
запросом
|
|||
5
Rounder
11.04.13
✎
13:14
|
(3) Сортировка ничего не даст - если не вводить дополнительных реквизитов ТЗ, т.к. у записей с одинаковым ключом нет идентификаторов нахождения на временной оси или в таблице значение (номер строки).
|
|||
6
Rounder
11.04.13
✎
13:15
|
(4) Можно пример?
|
|||
7
zladenuw
11.04.13
✎
13:27
|
(0) а замером, где долго ?
|
|||
9
Maxus43
11.04.13
✎
13:31
|
(6) пример чего? ТЗ в запрос как воткнуть?
|
|||
10
Rounder
11.04.13
✎
13:31
|
(7) Приведенный цикл.
|
|||
11
Rounder
11.04.13
✎
13:33
|
(9) Пример запроса - как отобрать из массива данных только по одной записи на ключ.
Условие в (0) описано. |
|||
12
zladenuw
11.04.13
✎
13:33
|
ВЫБРАТЬ
ВложенныйЗапрос.Поле1 КАК Ключ, ВложенныйЗапрос.Поле2 КАК НомерСтроки ИЗ (ВЫБРАТЬ "Ключ" КАК Поле1, 1 КАК Поле2 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ "Ключ", 2) КАК ВложенныйЗапрос ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ МАКСИМУМ(ВложенныйЗапрос.Поле1) КАК Поле1, МАКСИМУМ(ВложенныйЗапрос.Поле2) КАК Поле2 ИЗ (ВЫБРАТЬ "Ключ" КАК Поле1, 1 КАК Поле2 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ "Ключ", 2) КАК ВложенныйЗапрос) КАК ВложенныйЗапрос1 ПО ВложенныйЗапрос.Поле1 = ВложенныйЗапрос1.Поле1 И ВложенныйЗапрос.Поле2 = ВложенныйЗапрос1.Поле2 |
|||
13
Rounder
11.04.13
✎
13:33
|
И условие дополнено еще в (3)
|
|||
14
palpetrovich
11.04.13
✎
13:33
|
ТЗ в ВТ + выбрать различные по ключу ...только надо подумать над "нужно оставить последнюю."
|
|||
15
Rounder
11.04.13
✎
13:35
|
(12) Благодарю. Буду смотреть.
|
|||
16
Maxus43
11.04.13
✎
13:35
|
>>то нужно оставить последнюю
это только нумерацию строк если сделать. Чито учитывая размер таблицы даже в запросе будет тормозить |
|||
17
acsent
11.04.13
✎
13:36
|
(5) сортировка даст то что одинаковые ключи будут друг за другом идти
|
|||
18
acsent
11.04.13
✎
13:36
|
Пока Ключ = СтарыйКлюч Цикл
Удалить() |
|||
19
Rounder
11.04.13
✎
13:38
|
(16) Так это и есть главный вопрос - нет поля для доп. упорядочивания.
(17) А сортировка как будет определять какой из ключей выше и ниже поставить если они одинаковы? Я знаю как решить проблему если добавить реквизит - например НомерСтроки. Я не знаю как решить ее при условиях описанных в (0) и (3). Пойду пока изучать запрос из (12). |
|||
20
PCcomCat
11.04.13
✎
13:38
|
(0) ТаблицаЗначений откуда берется?
|
|||
21
SherifSP
11.04.13
✎
13:40
|
А попробуй знаешь как, не записывать уникальный ключ в новую тз, а перебирать строки текущей тз и методом найти строки, искать строку по ключу.
Для Каждого СтрокаТЗ Из ТЗ1 Цикл Отбор = Новый Структура; Отбор.Вставить("Ключ" СтрокаТЗ.Ключ); ИскомаяСтрока= ТЗ1.НайтиСтроки(Отбор); Если ИскомаяСтрока.Количество() > 1 Тогда //Удаляешь строку ТЗ у которой в колонке "НомерСтроки" меньше значение КонецЕсли; КонецЦикла; |
|||
22
Rounder
11.04.13
✎
13:40
|
(20) Не важно откуда она берется.
Вопрос ведь в ином. Если я добавлю поле доп упорядочивания - то я решу свою задачу. Вопрос как решить задачу без доп поля. |
|||
23
Maxus43
11.04.13
✎
13:41
|
(22) дак (12) это не решает
|
|||
24
Rounder
11.04.13
✎
13:42
|
(21) Нету НомераСтроки :)
|
|||
25
Rounder
11.04.13
✎
13:42
|
(23) Похоже на то.
|
|||
26
palpetrovich
11.04.13
✎
13:42
|
(24) да?!! в ТЗ нет НомерСтроки?
|
|||
27
zladenuw
11.04.13
✎
13:43
|
(24) а там она и не надо
Если ИскомаяСтрока.Количество() > 1 Тогда Индекс = 0; Пока Истина Цикл Если ИскомаяСтрока.Количество()=1 Тогда Прервать; Иначе ИскомаяСтрока.Удалить(Индекс); Индекс=Индекс+1; КонецЕсли; КонецЦикла; КонецЕсли; |
|||
28
Maxus43
11.04.13
✎
13:43
|
(24) номера нет, есть ИНдекс
|
|||
29
Rounder
11.04.13
✎
13:44
|
(26) Я не это имел в виду - нет реквизита НомерСтроки - который не изменится после сортировки.
|
|||
30
PCcomCat
11.04.13
✎
13:44
|
(22) Если эта ТЗ из запроса получилась, то разница есть: нафига второй раз анализировать, если можно в первом сразу получить нужный результат?
|
|||
31
Rounder
11.04.13
✎
13:46
|
(30) Еще раз говорю - задача не в этом.
Есть условия описанные в (0) и в (3). Нужно ответить на один вопрос: возможна ли более оптимальная реализация нежели приведенная в (0). |
|||
32
Rounder
11.04.13
✎
13:48
|
(27) Не прокатит. Точнее прокатит - если все одинаковые ключи будут идти неделимыми группами.
Или я не прав? |
|||
33
zladenuw
11.04.13
✎
13:49
|
(32) отбор по таблице идет. ты получаешь массив строк где ключ = ключотбора
|
|||
34
Gossar1C
11.04.13
✎
13:50
|
еще можно свернуть)
|
|||
35
Gossar1C
11.04.13
✎
13:51
|
ТаблицаЗначений (ValueTable)
Свернуть (GroupBy) Синтаксис: Свернуть(<КолонкиГруппировок>, <КолонкиСуммирования>) Параметры: <КолонкиГруппировок> (обязательный) Тип: Строка. Имена колонок, разделенные запятыми, по которым необходимо группировать строки таблицы значений. <КолонкиСуммирования> (необязательный) Тип: Строка. Имена колонок, разделенные запятыми, по которым необходимо суммировать значения в строках таблицы значений. Описание: Осуществляет свертку таблицы значений по указанным колонкам группировки. Строки, у которых совпадают значения в колонках, указанных в первом параметре, сворачиваются в одну строку. Значения этих строк, хранящиеся в колонках, указанных во втором параметре, накапливаются. Важно! Списки колонок не должны пересекаться. Колонки, не вошедшие ни в один из списков колонок, после выполнения метода удаляются из таблицы значений. Доступность: Сервер, толстый клиент, внешнее соединение. |
|||
36
Rounder
11.04.13
✎
13:53
|
(35) Это ничего не дает.
(33) Да я суть понял. Сомнителен выигрыш по времени выполнения. |
|||
37
zladenuw
11.04.13
✎
13:53
|
(36) запрос. где группировки по максимуму. можно поидее без вложенных. только нужен индекс строки ключа
|
|||
38
Rounder
11.04.13
✎
13:54
|
Ладно.
Всем спасибо. Буду наверное вводить еще одно поле для доп. упорядочивания. |
|||
39
Gossar1C
11.04.13
✎
13:55
|
(36) делал загрузку с 2х прайсов притом в одном прайсе была одна строка с брендом Dextrim допустим, а во втором их 3 и более с разными номерами замены, мне этот метод очень помог
|
|||
40
Rounder
11.04.13
✎
13:57
|
(39) В данном случае он не подходит. Кроме поля "Ключ" в ТЗ есть еще несколько полей.
В (0) приводил код только для "Ключ" для простоты восприятия. |
|||
41
PiterPrg
11.04.13
✎
14:03
|
(40) тогда что-то типа так:
ТЗКол = ТЗ1.Скопировать( , "Ключ"); ТЗКол.Индексы.Добавить("Ключ"); ТЗКол.Свернуть("Ключ", ""); Сч = ТЗ1.Количество() - 1; Пока Сч >= 0 Цикл Стр = ТЗ1[Сч]; СтрКол = ТЗКол.Найти(Стр.Ключ, "Ключ"); Если СтрКол = Неопределено Тогда ТЗ1.Удалить(Стр); Иначе ТЗКол.Удалить(СтрКол); КонецЕсли; Сч = Сч - 1; КонецЦикла |
|||
42
sirsp
11.04.13
✎
14:33
|
ТЗ2 = ТЗ1.СкопироватьКолонки();
лС = новый Соответствие; Для н = - ТЗ1.Количество() + 1 По 0 Цикл лСтрока = ТЗ1[-н]; Если лС[лСтрока.Ключ] = неопределено Тогда лС.Вставить(лСтрока.Ключ, ИСТИНА); ЗаполнитьЗначенияСвойств(ТЗ2.Вставить(0), лСтрока); КонецЕсли; КонецЦикла; |
|||
43
Рэйв
11.04.13
✎
14:50
|
(0) как то так:
мСтрок=ТЗ.НайтиСтроки(Новый Структура("КолонкаКлюч",ЗначениеКлюч)); Если мСтрок.Количество()>1 Тогда Для Каждого строчкаТЗ Из мСтрок Цикл Если мСтрок.Индекс(ЭстрочкаТЗ)+1=мСтрок.Количество() Тогда Прервать; КонецЕсли; ТЗ.Удалить(строчкаТЗ); Конеццикла; КонецЕсли; |
|||
44
palpetrovich
11.04.13
✎
14:58
|
нарисовал на примере справочника НоменклатураЮ может пригодится?
// подготовка ТЗ Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Код, | Номенклатура.Наименование |ИЗ | Справочник.Номенклатура КАК Номенклатура |"; Результат = Запрос.Выполнить(); // собствеено (выводим тольлко различные по наименованию) Запрос = Новый Запрос; МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц; Запрос.Текст = "ВЫБРАТЬ | ТЗ.Код, | ВЫРАЗИТЬ(ТЗ.Наименование КАК СТРОКА(100)) КАК Наименование |ПОМЕСТИТЬ ВТ |ИЗ &ТЗ КАК ТЗ |; |ВЫБРАТЬ РАЗЛИЧНЫЕ | ВТ.Наименование КАК Наименование |ПОМЕСТИТЬ ВТ1 |ИЗ ВТ КАК ВТ |; |ВЫБРАТЬ | ВТ1.Наименование КАК Наименование, | ВТ.Код |ИЗ | ВТ1 КАК ВТ1 | ЛЕВОЕ СОЕДИНЕНИЕ | (ВЫБРАТЬ | ВТ.Наименование КАК Наименование, | МИНИМУМ(ВТ.Код) КАК Код | ИЗ ВТ КАК ВТ | СГРУППИРОВАТЬ ПО | ВТ.Наименование) КАК ВТ | ПО (ВТ.Наименование = ВТ1.Наименование) |УПОРЯДОЧИТЬ ПО | Наименование"; Запрос.УстановитьПараметр("ТЗ", ТЗ); Результат = Запрос.Выполнить(); |
|||
45
palpetrovich
11.04.13
✎
15:05
|
* после 1-го запроса забыл ТЗ = Результат.Выгрузить();
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |