Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > группы записей в таблице


Автор: Гость_dasha 18.8.2005, 15:09
Добрый день всем. Нужна помощь с таблицей. В ней содержатся записи про клиентов. Так вот нужно найти группы записей с одинаковыми именами, а еще лучше, чтобы можно было указать, скажем, сколько символов может несовпадать. Можно такое автоматически реализовать? Вот такая задача smile . Буду рада, если кто-то поможет разобраться.

Автор: Bes 18.8.2005, 15:12
на счет сколько символов, это надо подумать, а по именам дак это просто фильтр.
Код

select * from MyTab where KlientName like '%Сергей%'

Автор: Гость_dasha 18.8.2005, 15:22
Так в том то и дело, что заранее неизвестно, какие имена повторяются, а нужно найти все повторения и каждую группу имен как-то пронумеровать, например в отдельном поле.

Автор: Pakshin A. S. 18.8.2005, 15:25
А если вывести в DBGrid гуппированные записи при помощи GROUP BY и ручками все в них сделать...

Автор: Гость_dasha 18.8.2005, 15:35
Боюсь, придется, только это времени немало займет. Там потом еще в каждой группе записей проверять значение другого поля, а записей там примерно 20 000. smile

Автор: bursa 18.8.2005, 15:45
Лучше сформировать новый справочник имен с полем name и id(автоинкримент)

Код

insert into new_table
(name)
(select name  from table
group by name)



Потом заполняем новое поле, которое пронумеровывает группы
Код

update table t set t.id_new=(select id from new_table n where n.name=t.name)


Ну и еще - посмотреть кол-во в группе
Код


select name, count(*) as c from table
group by name


Автор: Гость_dasha 18.8.2005, 15:50
bursa, спасибо, попробую.

Автор: Pakshin A. S. 18.8.2005, 15:55
А может еще конкретнее задачу описать? С примерами... Может еще что-то надумается...

Автор: Гость_dasha 18.8.2005, 16:08
Конкретнее. Ну смысл в том, что таблица составляется из списков, составленных в разных филиалах (при этом разные люди могут одну фамилию немного по-разному написать). Там информация, кому сколько выдавали компенсаций. Но один человек не может два раза получить компенсацию на похороны даже с разных счетов, или два раза маленькую компенсацию с одного счета, только с разных. Короче, ищем нарушения. Смысл в том, чтобы найти всех повторяющихся и проверить, кто сколько получал.
Я делала вручную, обычными массивами и стринггридом, оно работает, но занимает сильно много ресурсов и времени при больших объемах данных, а в SQL я новичок.

Автор: Bes 19.8.2005, 08:02
может проще штрафовать криворуких операторов?
И кстати, для такого дела (я подозреваю это разовая задача или скажем ежемесячная) можно пожертвовать всеми ресурсами и скажем целой ночью.

Автор: Гость_dasha 19.8.2005, 09:32
да нет, у компа просто не хватает памяти
Буду как-то выкручиваться, все равно надо учить SQL. smile

Автор: Bes 19.8.2005, 10:35
Думаю SQL тут вам врядли поможет, так вот даже в голову ничего не приходит сразу - это ведь больше статистика и отличия могут быть разные.
Хотя опишите поподробнее проблему: ведь насколько я понял человек не должен получить сумму два раза, но он ее и не поучи т.к. паспортные данные не те, а если они два раза одинаковые и он может по ним получить суму 2 раза, то нужно искать не различающиеся а совпадающие записи.... а это гораздо проще. Так?

Автор: Pakshin A. S. 19.8.2005, 10:39
Впринцепе и с паспортными данными может ошибка закрасться...

Был алгоритм распознавания, как FineReader буквочки со сканера... Может его можно прикрутить для установления "похожести", но все-равно будет достаточно долго работать и полного автоматизма не получить... smile

Автор: Bes 19.8.2005, 11:08
закрасться то она может, только по этим данным потом сумму не получить....

Автор: Гость_dasha 19.8.2005, 11:18
2Bes: ну да, одинаковые, ведь ищем повторяющиеся фамилии.
Просто у одного человека может быть несколько счетов в одном филиале, или в разных. Он может получить компенсацию 50 по одному разу с каждого счета, а 150 или 500 один раз на человека.

2Pakshin A. S.: да ладно, буду брать только повторяющиеся фамилии.

Автор: Гость_dasha 19.8.2005, 11:22
2Bes: то есть человек имеет право получить то, что я написала, но надо проверить, не удалось ли кому нибудь это нарушить.

Автор: Гость_dasha 19.8.2005, 11:30
То есть человек имеет право все это получить, но надо проверить, не удалось ли кому-нибудь поснимать лишних денег.

Автор: Bes 19.8.2005, 13:22
ну тогда запрос должен выглядеть как-то так
Код

select count(*), Familija from scheta group by Familija having count(*)>1

Автор: Гость_dasha 19.8.2005, 14:00
Ага, я где-то так и сделала, как раз заработало smile . Тут теперь другой прикол. Сохраняю все выбранное (фамилии и кол-во>1) в таблицу NewT, чтобы потом объединить с первой и вывести все нужные записи. Но при сохранении все не латинские буквы превращаются в какие-то закорючки, не то DOS-кодировка, не то не поймешь что. smile
Что мне с этим делать smile

Автор: Гость_dasha 19.8.2005, 14:22
Все, уже сделала, оказалось драйвер в BDE.

Автор: Гость_dasha 22.8.2005, 13:39
Ура, ура, получилось. Спасибо всем, кто откликнулся, а также создателям Access. Кто сказал, что SQL не поможет? Поможет.
В общем, если кому интересно, что получилось, то вот:

главная таблица называлась data.

create table NewT //создаем новую, куда запишем тех, кто повторяется
(name char(30));

INSERT INTO NewT (name)
SELECT Data.Ф_И_О
FROM Data
WHERE
"data"."Дата">:Date //было ограничение по дате
GROUP BY Data.Ф_И_О
HAVING (((Count(*))>1));

create table Rep //таблица с фамилиями тех, у кого есть нарушения
(account integer,
name char(30));

INSERT INTO Rep (name,account) //ищем, кто на один счет получал 50 и
SELECT Data.Ф_И_О,"data"."Номер счета"
FROM NewT INNER JOIN Data ON NewT.name = Data.Ф_И_О
WHERE ((("Data"."Сумма операции")<=50)) AND
"data"."Дата">:Date
GROUP BY "data"."Ф_И_О","data"."Номер счета"
HAVING (((Count(*))>1));

INSERT INTO Rep (name)
SELECT Data.Ф_И_О
FROM NewT INNER JOIN Data ON NewT.name = Data.Ф_И_О
WHERE ((("Data"."Сумма операции")>50)) AND
"data"."Дата">:Date
GROUP BY "data"."Ф_И_О"
HAVING (((Count(*))>1));

select "data".*
from Data INNER JOIN Rep ON (Rep.name = Data.Ф_И_О AND
Rep.account = "data"."Номер счета");

Автор: Гость_dasha 22.8.2005, 15:12
точнее так

select "data".*
from Data INNER JOIN Rep ON ((Rep.name = Data.Ф_И_О AND
Rep.account Is Null) OR (Rep.name = Data.Ф_И_О AND
Rep.account = "data"."Номер счета"))
order by "data"."Ф_И_О","data"."Номер счета";

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)