Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Формирование строки


kaini ©   (2011-03-04 05:21:00) 

Здравствуйте, мастера!
Уж долгое время не могу решить одну задачу. Есть таблица с записями:
1999
2000
2001
2003
2005
2006
2007
....

Надо перевести в следующий вид:
1999-2001, 2003, 2005-2007, ...
и сохранить в другой таблице.
Подскажите пожалуйста!
Спасибо!


Кщд   (2011-03-11 18:31:00) [1]

>Очень злой   (10.03.11 14:55) [11]
в Oracle можно получить требуемое именно в таком виде, как нужно автору, и всего лишь одним проходом по таблице
про небрежные альясы(alias) у таблиц лучше промолчать)

информация к размышлению:

select k.fyear, k.fyear - row_number() over (order by k.fyear) group_id
from sometable k


Очень злой   (2011-03-10 14:55:00) [2]

Как вариант, можно, что-то типа этого

SELECT   CONCAT (TO_CHAR (a.YEAR), NVL ((SELECT '-' FROM mytable WHERE YEAR = a.YEAR + 1), ','))
  FROM mytable a
  WHERE NOT EXISTS (SELECT NULL FROM mytable WHERE YEAR = a.YEAR + 1)
     OR NOT EXISTS (SELECT NULL FROM mytable WHERE YEAR = a.YEAR - 1)
ORDER BY a.YEAR


тогда из этого:
1999
2000
2001
2003
2005
2006
2007
получим такое:
1999-
2001,
2003,
2005-
2007,

А дальше можно собрать все в одну строку, удалить последнюю зяпятую и "засунуть" в другую таблицу.


Боброжелатель   (2011-03-04 11:41:00) [3]

> Кщд   (04.03.11 10:51) [8]

type
 readvaluefunc = function(out value: integer): boolean;
 writevalueproc = procedure(value: integer);
 writeintervalproc = procedure(start, finish: integer);

procedure compact(readfunc: readvaluefunc; writevalue: writevalueproc; writeinterval: writeintervalproc);
var
 finish: integer;
 next: integer;
 start: integer;

 procedure writeresult;
 begin
   if start = finish then
     writevalue(start)
   else
     writeinterval(start, finish);
 end;

begin
 if readfunc(start) then
 begin
   finish := start;
   while readfunc(next) do
   begin
     if (next - finish) <> 1 then
     begin
       writeresult;
       start := next;
     end;
     finish := next;
   end;
   writeresult;
 end;
end;


Anatoly Podgoretsky   (2011-03-04 10:58:00) [4]


> слово "файл" Вы заметили между строк?)

Что бы это заметить нужна пара поллитр.
Автор просто не умеет правильно задавать вопросы.


Кщд   (2011-03-04 10:51:00) [5]

>Боброжелатель   (04.03.11 10:39) [7]
до уточнения автора приводить код - бессмысленно)


Боброжелатель   (2011-03-04 10:39:00) [6]

у меня позиция простая: если в ответе приводят код, то он должен быть рабочим.

Он рабочий.

слово "файл" Вы заметили между строк?

Автор вопроса не уточнял механизм хранения "таблицы". Как, впрочем, и определение того, что он подразумевает под "таблицей".

У меня позиция простая: не нравится приведенный код, приведи свой.


Кщд   (2011-03-04 10:33:00) [7]

>Боброжелатель   (04.03.11 10:10) [3]
слово "файл" Вы заметили между строк?)
у меня позиция простая: если в ответе приводят код, то он должен быть рабочим.
никому не навязываю и обсуждать это не собираюсь.


Боброжелатель   (2011-03-04 10:25:00) [8]

> Кщд   (04.03.11 10:22) [4]
> 1999
> 2006
> 2000
> 2001
> 2003
> 2005
> 2007


Исходные данные не соответствуют поставленной автором вопроса задаче.
Отсортируешь - тогда и приходи.


Кщд   (2011-03-04 10:22:00) [9]

>Боброжелатель   (04.03.11 10:10) [3]
1999
2006
2000
2001
2003
2005
2007


Боброжелатель   (2011-03-04 10:10:00) [10]

function form_string(filename: string): string;

 procedure appendresult(start, finish: integer);
 begin
   if result <> '' then
     result := result + ', ';
   if start = finish then
     result := result + inttostr(start)
   else
     result := result + inttostr(start) + '-' + inttostr(finish)
 end;

var
 finish: integer;
 next: integer;
 start: integer;
 f: text;
begin
 result := '';
 assign(f, filename);
 reset(f);
 try
   if not eof(f) then
   begin
     readln(f, start);
     finish := start;
     while not eof(f) do
     begin
       readln(f, next);
       if (next - finish) <> 1 then
       begin
         appendresult(start, finish);
         start := next;
       end;
       finish := next;
     end;
     appendresult(start, finish);
   end;
 finally
    closefile(f);
 end;
end;


Кщд   (2011-03-04 09:20:00) [11]

>kaini   (04.03.11 05:21)  
СУБД?


И. Павел   (2011-03-04 08:29:00) [12]

Сперва выбрать все данные, упорядочив их по дате. А потом First + whine not eof ... Next. Значение даты на предыдущем шаге итерации сохраняем и сравниваем с текущем. Если отличается больше, чем на год, то формируем интервал XXXX-XXXX и начинаем формировать новый интервал, сохранив ее начальную дату. Если нужно, могу расписать в виде программы. Но позже...


Наверх

Титульная страница Поиск, карта сайта Написать письмо