Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Базы данных
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 10.07.2008, 12:48
Kirill1987 Kirill1987 вне форума
Прохожий
 
Регистрация: 10.07.2008
Сообщения: 10
Репутация: 10
По умолчанию Проблема с сортировкой

Есть база данных access, в ней две таблицы
1) Ведомость на отгрузку - дата,Направление, расстояние,перевозчик, подтверждение
2) Перевозчик - название, процентная доля
Надо в первой таблице отсортировать записи по расстоянию, в 4 категории 1 - до 200км, 2- 200-400км, 3 - 400-600км, более 600км
Записям до 200 км - поставить в поле перевозчик занчение - компания
Остальные поля "перевозчик" надо автоматически распределить между компаниями перевозчиками, в соот с их долями (доли указаны в процентах во второй моей таблице)

Вот в общем в чем пробема, помогите пожалуйста уже голову сломал, даже в какую сторону думать не знаю, если нужны какие либо уточнения тут же отпишу
Ответить с цитированием
  #2  
Старый 10.07.2008, 19:24
Аватар для Yurk@
Yurk@ Yurk@ вне форума
Специалист
 
Регистрация: 07.09.2007
Адрес: Украина, г. Днепропетровск
Сообщения: 892
Версия Delphi: 7 + ОгнеПтица
Репутация: выкл
По умолчанию

Код:
Table1.First;
while Table1.Eof do
begin
if Table1.FieldByName('RAST').Integer<=200 
 then 
  begin
  Table1.Edit;
  Table1.FieldByName('PEREVOZ').String:='Компания';
  Table1.Post;
  end;
Table1.Next;
end;
А дальше в том же духе!
__________________
Поживу - увижу, Доживу - узнаю, Выживу - учту.
[P.S.]->Выражая благодарность за помощь - Вы получаете шанс на помощь в следующий раз
Ответить с цитированием
  #3  
Старый 10.07.2008, 20:56
Kirill1987 Kirill1987 вне форума
Прохожий
 
Регистрация: 10.07.2008
Сообщения: 10
Репутация: 10
По умолчанию

Прости моя ошибка, проблема в том что пишу это дело все на delphi, и работаю с компонентами ado для отображения следовательно dbgrid использую
Ответить с цитированием
  #4  
Старый 10.07.2008, 20:58
Kirill1987 Kirill1987 вне форума
Прохожий
 
Регистрация: 10.07.2008
Сообщения: 10
Репутация: 10
По умолчанию

Прости моя\ ошибка, клиент пишу на делфи использую компоненты ado, для отображения dbgrid, как в этом случае это написать, поясни пожалуйста
Ответить с цитированием
  #5  
Старый 10.07.2008, 21:04
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,105
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Первое - группировка, не знаю, прокатит или нет, но можно попробовать.

Код:
SELECT 
  RASSTOYANIE,
  PEREVOZCHIK,
  CASE
    WHEN RASSTOYANIE <= 200 THEN 1
    WHEN RASSTOYANIE > 200 AND RASSTOYANIE <= 400 THEN 2
    WHEN RASSTOYANIE > 400 AND RASSTOYANIE <= 600 THEN 3
    ELSE 4
  END AS CATEGOTIYA
FROM VEDOMOST
SORT BY CATEGOTIYA
-- Если здесь не возьмет, то сортировать по полю RASSTOYANIE
-- Это не имеет значения

Это получение. Такой запрос можно и группировать.

Теперь что по поводу установки.
Фактически, тебе надо посчитать кол-во элементов и поделить их в соотв. пропорции (кстати, а у тебя в таблице перевозчиков суммарная доля не больше 100%?).

Тут делаем в несколько шагов.
1. Устанавливаем всем расстояниям <= 200 значение "компания" (делаем запросом, что бы не нагружать сеть - пусть СУБД трудится):
Код:
UPDATE VEDOMOST
SET PEREVOZCHIK = 'компания'
WHERE RASSTOYANIE <= 200

2. Теперь нам надо установить общее кол-во записей для распределения по другим перевозчикам. Опять же делаем всего 1 запрос:
Код:
SELECT count(*) FROM VEDOMOST WHERE RASSTOYANIE > 200

Фактически мы получим кол-во неустановленных строк.

Здесь маленнькая ремарка.
В эти 2 выборки не попадут ведомости, у которых значение расстояния не установлено, т.е. равно NULL. Что бы их добавить в тот или иной запрос, надо в конце добавить "OR RASSTOYANIE IS NULL" (без кавычек, соответсвенно).

3. Теперь нам надо посчитать сколько на 1% доли перевозчиков приходится записей в ведомосях.
Здесь, во первых, стахуемся от того, что суммарная доля м.б. > 100%.
Да, предполагаем, что там у тебя хранятся проценты, т.е. числа от 0 до 100.

Код:
SELECT SUM(DOLYA) FROM PEREVOZCHIKI

Тут мы получили суммарную долю всех перевозчиков в %%.

4. Теперь вычисляем сколько нам надо записей на 1%.
Это уже делаем в Delphi, хотя можно было сделать и за 1 шаг вместе с пп. 2 и 3, но тут есть специфичность от БД, так что не будем торопиться.

Код:
var
  ItemsPerPercent : Integer;
begin
  // Query1 - запрос из шага 2
  // Query2 - запрос из шага 3

  ItemsPerPercent := Round(Query1.Fields[0].AsInteger/Query2.Fields[0].AsInteger);
  If ItemPerPercent = 0 Then Inc(ItemPerPercent);

Очередное замечание. If ItemPerPercent = 0 Then Inc(ItemPerPercent) - страховка от ошибки, когда на 1% приходится меньше 1 записи. В приципе, в таком случае кому-то недостанется чего везти, но это уже их пробема.

5. Теперь нам надо расставить перевозчиков.
Собственно, надо взять каждого перевозчика и посчитать сколько записей приходится на его долю, а затем пройти по ведомостям нужное кол-во строк и поставить их в значение этого перевозчика. Тут нам потребуется 2 запроса и маленький код на Delphi.

Запрос А. Получение перевозчиков. При этом сортируем их обратно пропорционально их доле (наиболее вероятно, что тебе все-таки хочется перевозчиков с большой долей удержать, загрузив их работой).

Код:
SELECT PEREVOZCHIK, DOLYA
FROM PEREVOZCHIKI
ORDER BY DOLYA DESC

Запрос Б. Получение неназначенных ведомостей. Кстати, их тоже можно как-нить отсортировать, но тут я не знаю от чего это может зависей. Запрос аналогичен запросу шага 2, но тут мы получаем список, а не одно число. Здесь нас интересует просто поле, где надо указать перевозчика, т.к. остальны ерасчеты мы уже сделали, ну и поле ID (надеюсь ты его не забыл) для идентификации записи.

Код:
SELECT ID, PEREVOZCHIK FROM VEDOMOST WHERE RASSTOYANIE > 200

И теперь маленький кусочек на Delphi, который расставит перевозчиков.
Сами значения будут устанавливаться с помощью запроса, т.к. мне прсто так удобнее.
Код:
const
  UPD_QUERY = 'UPDATE VEDOMOST SET PEREVOZCHIK = ''%s'' WHERE ID = %d';
var
  N : Integer;
  C : Integer;
begin
  // Query3 - запрос А
  // Query4 - запрос Б
  // Query5 - параметризованный запрос, которым мы и будем ставить значения.
  Query3.Open;
  Query4.Open;
  Query5.SQL.Clear;
  
  Query3.First;
  Query4.First;

  C := 0;
  N := Query3.FieldByName['DOLYA'].AsInteger * ItemsPerPercent; // Кол-во записей для перевозчика.
  While Not Query4.Eof Do
    Begin
      Query5.SQL.Clear;
      Query5.SQL.Add(Format('UPD_QUERY',[ Query3.FieldByName('PEREVOZCHIK'].AsString,Query4.FieldByName['ID'].AsInteger));
      Query5.ExecSQL;
      Inc(C);
      If C > N Then
        Begin
           Query3.Next;
           N := Query3.FieldByName['DOLYA'].AsInteger * ItemsPerPercent; // Кол-во записей для перевозчика.
           C := 0;
        End;
      Query4.Next;
    End;

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

PS. Можно написать и короче. Для себя бы я сократил всю эту кашу на треть и сделал бы это скорее на сервере (принцип не отличается) в виде хранимой процедуры, а с клиента (из Дельфей) просто дергал бы эту процедуру и выводил результат. Но зато тут подробно рассмотрен алгоритм решения такой задачи.

Последний раз редактировалось lmikle, 10.07.2008 в 21:35.
Ответить с цитированием
  #6  
Старый 12.07.2008, 06:31
Kirill1987 Kirill1987 вне форума
Прохожий
 
Регистрация: 10.07.2008
Сообщения: 10
Репутация: 10
По умолчанию

Спасибо большое сегодня как проснусь сразу начну ковырять, уже неделю читаю все что попадается по базам Просто никогда не связывался, еще раз спасибо
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:40.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025