![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Формирование строки
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 и начинаем формировать новый интервал, сохранив ее начальную дату. Если нужно, могу расписать в виде программы. Но позже...