Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 24.04.2013
Сообщений: 14
1

Убрать повторяющиеся элементы

25.04.2013, 13:43. Показов 3113. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Приветствую. Имеется небольшая проблема с выводом результатов запроса из базы в Treeview.
Суть в следующем: Имеется база с кулинарными рецептами, ингредиентами и способом приготовления.
При поиске в базе по одному ингредиенту одного блюда - появляется 1 рецепт:
(см. скриншот 1)
Если же к поиску добавить ещё 1 ингредиент, содержащийся в этом блюде, то в результатах появляется ещё 1 копия этого блюда:
(см. скриншот 2, который с обведенными значениями)

Т.е. для поиска берутся элементы из ListBox2 и по ним идет поиск в базе:

Собственно сам код процедуры запроса:
Delphi
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
procedure Tmain_form.Button3Click(Sender: TObject);
var n,k,m,b,o,z:integer;
    v,tmp_v:boolean;
    tmp:string;
    x,y:ttreenode;
begin
//Тут очищаем дерево перед выводом
  TreeView1.Items.Clear;
  TreeView1.Items.AddChild(TreeView1.Items.GetFirstNode,'Рецепты');
//Строим ветви для каждого типа блюда
  for b:=1 to food_num do begin
   x:=TreeView1.Items.AddChild(TreeView1.Items.Item[0],types_of_food[b,2]);
   for o:=0 to ListBox2.Items.Count-1 do begin
    ADOQuery1.Close;
    ADOQuery1.SQL.Clear;
//Ну и сам запрос
    ADOQuery1.SQL.Add('SELECT * From cookbook,cookbook_food,food Where '+ '(cookbook.type="'+types_of_food[b,1]+'")AND(cookbook_food.cbid=cookbook.id)AND(food.id=cookbook_food.pfid)AND(food.title="'+listbox2.Items.Strings[o]+'");');
    ADOQuery1.Open;
  for m:=1 to ADOQuery1.RecordCount do begin
    TreeView1.Items.AddChild(x,ADOQuery1.FieldList.Fieldbyname('cookbook.title').AsString);
   ADOQuery1.RecNo:=m;
  end;
 end;
end;
end;
А теперь сам вопрос: Как убрать из TreeView повторяющиеся элементы при поиске по нескольку ингредиентов?
Заранее благодарю.
Миниатюры
Убрать повторяющиеся элементы   Убрать повторяющиеся элементы  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.04.2013, 13:43
Ответы с готовыми решениями:

Сортировка, убрать повторяющиеся элементы
Необходимо ввести рандомно целые числа, затем провести сортировку а в конце убрать повторяющийся...

Убрать повторяющиеся элементы в массиве
Всем доброго времени суток! Подскажите пожалуйста как убрать повторяющиеся элементы в массиве?...

Убрать повторяющиеся элементы одномерного массива
Убрать повторяющиеся элементы одномерного массива. Есть одномерный динамический массив(длина 40),...

Напомните формулу (убрать или удалить , скрыть, повторяющиеся элементы)
Есть одномерный массив нужно убрать или удалить , скрыть (то что будет проще), повторяющиеся...

19
59 / 59 / 7
Регистрация: 11.03.2013
Сообщений: 191
25.04.2013, 14:57 2
VasyaAgPro, попробуйте добавить DISTINCT в ваш SQL запрос.
Начинаться будет так:
SQL
1
SELECT DISTINCT * FROM
.
1
0 / 0 / 0
Регистрация: 24.04.2013
Сообщений: 14
25.04.2013, 15:11  [ТС] 3
VitoAcidrain, Да, я пробовал это. Если не ошибаюсь - эта функция находит повторяющиеся элементы в базе и не выводит их несколько раз. Но у меня в базе повторяющихся элементов нет, поэтому эта функция бесполезна.
Проблема происходит при формировании дерева, может есть какая то процедура, позволяющая сравнить все уже выведенные в TreeView значения и убрать совпадения?
0
969 / 644 / 97
Регистрация: 01.11.2012
Сообщений: 1,447
25.04.2013, 15:40 4
VasyaAgPro, для формирования списка наименований в тело запроса не добавляете ингредиенты (+ делайте Distinct) - и будут вам названия в одном экземпляре.
1
59 / 59 / 7
Регистрация: 11.03.2013
Сообщений: 191
25.04.2013, 15:45 5
Можно подумать о проверке через IF.
Но в вашем запросе ещё одно смущает.
У вас
SQL
1
food.title="'+listbox2.Items.Strings[o]+'"
Но обычно в таком случаи запрос должен выглядеть так:
SQL
1
food.title IN ('условие 1', 'условие 2')
.

Добавлено через 3 минуты
Waddonator, осмелюсь предположить, что запрос в таком случаи выведет все блюда из категории, а не единственный нужный.
0
969 / 644 / 97
Регистрация: 01.11.2012
Сообщений: 1,447
25.04.2013, 15:58 6
VitoAcidrain, почему это
Цитата Сообщение от VitoAcidrain Посмотреть сообщение
запрос в таком случаи выведет все блюда из категории, а не единственный нужный
если условие WHERE остается?
0
59 / 59 / 7
Регистрация: 11.03.2013
Сообщений: 191
25.04.2013, 16:11 7
Цитата Сообщение от Waddonator Посмотреть сообщение
если условие WHERE остается?
Если я правильно понял, то
SQL
1
cookbook.type="'+types_of_food[b,1]+'"
будет подставлять: Супы, Салаты, Напитки и т.д.. Т.е выборка будет осуществляться по категории еды.
Остальные условия, кроме ингредиентов, служат для связи двух таблиц.
0
969 / 644 / 97
Регистрация: 01.11.2012
Сообщений: 1,447
25.04.2013, 16:18 8
VitoAcidrain, нужно оставить все как было, только вместо
SQL
1
SELECT * FROM ...
написать
SQL
1
SELECT DISTINCT <поле с наименованием> FROM ...
0
59 / 59 / 7
Регистрация: 11.03.2013
Сообщений: 191
25.04.2013, 16:43 9
Waddonator, на счет DISTINCT я ТС говорил. Судя по всему это не работает.
А разницы между * и <поле с наименованием> не должно быть.
Все равно инфа берется из столбца с наименованиями.
Delphi
1
ADOQuery1.FieldList.Fieldbyname('cookbook.title').AsString
0
969 / 644 / 97
Регистрация: 01.11.2012
Сообщений: 1,447
25.04.2013, 16:49 10
VitoAcidrain, "должно", "не должно"... Вы сначала попробуйте, а потом говорите. Не хочу вас расстраивать, разница между одним полем и множеством полей, все таки, есть.
0
0 / 0 / 0
Регистрация: 24.04.2013
Сообщений: 14
25.04.2013, 16:50  [ТС] 11
Waddonator, Буду благодарен, если на примере полного запроса покажите, не совсем понятно, что имеете ввиду, т.к. просто DISTINCT не работает. Если требуется структура базы, сделаю скрин, хотя, кажется, и так по запросу она понятна...
И надеюсь мы правильно друг друга поняли насчет того, что в итоге должны выводиться несколько разных блюд по всем имеющимся ингредиентам, а не конкретно одно: (см.скриншот)
Миниатюры
Убрать повторяющиеся элементы  
0
969 / 644 / 97
Регистрация: 01.11.2012
Сообщений: 1,447
25.04.2013, 16:55 12
VasyaAgPro, в каком поле хранится название типа "суп овощной"?

Добавлено через 1 минуту
Delphi
1
ADOQuery1.SQL.Add('SELECT DISTINCT cookbook.title From cookbook,cookbook_food,food Where '+ '(cookbook.type="'+types_of_food[b,1]+'")AND(cookbook_food.cbid=cookbook.id)AND(food.id=cookbook_food.pfid)AND(food.title="'+listbox2.Items.Strings[o]+'");');
0
0 / 0 / 0
Регистрация: 24.04.2013
Сообщений: 14
25.04.2013, 17:02  [ТС] 13
Waddonator, текстовое поле 'title', таблицы cookbook:
Миниатюры
Убрать повторяющиеся элементы  
0
969 / 644 / 97
Регистрация: 01.11.2012
Сообщений: 1,447
25.04.2013, 17:04 14
VasyaAgPro, выше написал. Пробуйте.
0
0 / 0 / 0
Регистрация: 24.04.2013
Сообщений: 14
25.04.2013, 17:36  [ТС] 15
Waddonator,
Ошибка, ругается на этот cockbook.title, что он не найден:
Миниатюры
Убрать повторяющиеся элементы  
0
969 / 644 / 97
Регистрация: 01.11.2012
Сообщений: 1,447
25.04.2013, 17:42 16
VasyaAgPro, выложите проект, ща разберемся.

Добавлено через 3 минуты
в 21 строке
Delphi
1
ADOQuery1.FieldList.Fieldbyname('cookbook.title').AsString
замените на
Delphi
1
ADOQuery1.Fieldbyname('title').AsString
1
0 / 0 / 0
Регистрация: 24.04.2013
Сообщений: 14
25.04.2013, 17:51  [ТС] 17
Waddonator, вот:
Вложения
Тип файла: zip workedit.zip (432.2 Кб, 11 просмотров)
0
969 / 644 / 97
Регистрация: 01.11.2012
Сообщений: 1,447
25.04.2013, 18:09 18
В логике ошибка. Замените код на следующий
Delphi
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
procedure Tmain_form.Button3Click(Sender: TObject);
var n,k,m,b,o,z:integer;
    v,tmp_v,dup:boolean;
    tmp,s:string;
    x,y:ttreenode;
    crc:Dword;
    item:TTreeNode;
begin
   //Î÷èùàåì äåðåâî, ôîðìèðóåììåòàêîìïîíåíò 'Ðåöåïòû'
   TreeView1.Items.Clear;
   TreeView1.Items.AddChild(TreeView1.Items.GetFirstNode,'Ðåöåïòû');
   //Ñòðîèì âåòêó äëÿ êàæäîãî òèïà ïèùè
   for b:=1 to food_num do begin
      x:=TreeView1.Items.AddChild(TreeView1.Items.Item[0],types_of_food[b,2]);
      ADOQuery1.Close;
      ADOQuery1.SQL.Clear;
      ADOQuery1.SQL.Add('SELECT DISTINCT cookbook.title From cookbook,cookbook_food,food Where '+ '(cookbook.type="'+types_of_food[b,1]+'")AND(cookbook_food.cbid=cookbook.id)AND(food.id=cookbook_food.pfid) AND (');
      for o:=0 to ListBox2.Items.Count-1 do begin
         if o<>0 then ADOQuery1.SQL.Add(' OR ');
         ADOQuery1.SQL.Add('(food.title="'+listbox2.Items.Strings[o]+'")');
      end;
      ADOQuery1.SQL.Add(')');
      ADOQuery1.Open;
      for m:=1 to ADOQuery1.RecordCount do begin
         TreeView1.Items.AddChild(x,ADOQuery1.Fieldbyname('title').AsString);
         ADOQuery1.RecNo:=m;
      end;
   end;
end;
Добавлено через 1 минуту
И проверку поставьте, если ничего не выбрано, то создать пустое дерево.
2
0 / 0 / 0
Регистрация: 24.04.2013
Сообщений: 14
25.04.2013, 18:11  [ТС] 19
Waddonator, Спасибо огромное, очень выручили.
0
969 / 644 / 97
Регистрация: 01.11.2012
Сообщений: 1,447
25.04.2013, 18:18 20
VasyaAgPro, кроме того, там еще ошибка есть. Вместо
Delphi
1
2
3
4
for m:=1 to ADOQuery1.RecordCount do begin
   TreeView1.Items.AddChild(x,ADOQuery1.Fieldbyname('title').AsString);
   ADOQuery1.RecNo:=m;
end;
напишите
Delphi
1
2
3
4
while not ADOQuery1.Eof do begin
   TreeView1.Items.AddChild(x,ADOQuery1.Fieldbyname('title').AsString);
   ADOQuery1.Next
end;
1
25.04.2013, 18:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.04.2013, 18:18
Помогаю со студенческими работами здесь

Динамические массивы: убрать элементы, повторяющиеся больше двух раз
Нужно написать программу используя динамические массивы, которая будет убирать элементы...

Задача заключается в том что бы сложить 2 массива, и убрать повторяющиеся элементы
Задача заключается в том что бы сложить 2 массива, и убрать повторяющиеся элементы,я смог сложить и...

Дана матрица.Заменить все повторяющиеся элементы - 1, а не повторяющиеся - 0
Дана матрица. Заменить все повторяющиеся элементы - 1, а не повторяющиеся - 0. Как мне заменить?...

Все повторяющиеся элементы матрицы заменить на 0,а не повторяющиеся на 1
Дана матрица размера n на m (n&gt;=5;m&gt;=5).Все повторяющиеся элементы заменить на 0,а не повторяющиеся...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru