Модераторы: Akella

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сортировка через одного, выбор записей поочереди 
:(
    Опции темы
Akella
Дата 29.11.2007, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



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

Есть в таблице поле числовое, в котором хранится что-то типа
1
1
1
2
3
3
3
4
4
1

как бы отсортировать в таком порядке:
1
2
3
4
1
2
3
4
1
2
3
4
1
2
1
2
1

т.е. как бы выхватывая из таблицы записи в таком специальном порядке:
Вот в чём проблема: разные агентства дают в редакцию газеты файлы объявлений. Это всё заливается в базу данных.
Но при экспорте в текстовый файл общей информации нужно выводить объявления таким способом:
одно объявление первого агентства, одно второго агентства, одно третьего, потом опять одно первого агентства, одно второго и т.д.

ну в таблице просто хранятся ссылки на id другой таблицы-справочника, связь через внешний ключ.

Код

for select .....

....

    select TREKLAMA.ID_AGENCY,
           TREKLAMA.id,
           TREKLAMA.TEXT,
           TREKLAMA.PHONE,
           TVID.NAME

      from TREKLAMA, TVID /*, TTYPE, TRAZDEL, TRUBRIKA, TNAPR, TREGION*/

      where TREKLAMA.ID = :ID
      and   TVID.ID     = TREKLAMA.ID_VID

      GROUP by 1, 2, 3, 4, 5

      into
           :ID1,
           :ID_AGENCY1,
           :TEXT,
           :PHONE,
           :TAG
      ;

    suspend;


Это сообщение отредактировал(а) Akella - 29.11.2007, 20:55
PM MAIL   Вверх
Akella
Дата 29.11.2007, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



всё храниться в treklama

Добавлено через 3 минуты и 34 секунды
я думаю, что тут нужно делать экспорт через дельфи в текст в разные файлы, потом поочереди из каждого файла заливать выдёргивая по одной записи из каждого файла в другую временную таблицу, из которой уже и формировать окончательный результат
PM MAIL   Вверх
Deniz
Дата 30.11.2007, 07:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 22
Всего: 44



Akella, можно добавить в таблицу поле "№ объявления" и вести его по каждому агенству.
Есть некоторые ограничения, если нужно указывать период по датам, тогда можно реализовать через временную таблицу, что-то вроде
Код
declare ...
npp = 0;
old_ida = 0;
ident = gen_id(..., 1); -- для определения уникальности выборки
for select t.ID_AGENCY, t.id 
  from treklama t 
  where (t.date between ... and ...)
  into : ida, :id
do begin
  if (old_ida = ida) then
    npp= npp + 1;
  else
  begin
    npp = 1;
    old_ida = ida;
  end
  insert into vtable(ident, id, npp) values (:ident, :id, :npp);
  for select ... 
    from treklama t inner join vtable v on (v.id = t.id)
    where ident = :ident
    order by npp, ID_AGENCY, ...
    into ...
    do suspend;
end

код писал без проверки, поэтому ... проверяй.
после выборки клиент посылает запрос 
Код
delete from vtable where ident = :ident 

можно попробовать без временной, но это надо думать


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
VOS
Дата 30.11.2007, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 31.1.2007

Репутация: нет
Всего: 8



Можно попробовать создать таблицу TEMP_ID из одного столбца ID_MAX_RECL (для ускорения можно еще и ID_AGENT)

потом в цикле по агентствам выбирать для каждого максимальный ID_RECL для агентства, если ID_RECL not in (select ID_MAX_RECL from TEMP_ID where ID_AGENT=:ID_AGENT))
ну и добавлять этот ID_RECL в TEMP_ID после выборки

естественно перед циком delete from ID_MAX_RECL
(т.к. я не знаю поддерживает ли сейчас FireBird временные таблицы как  MS SQL)





Это сообщение отредактировал(а) VOS - 30.11.2007, 11:06
PM MAIL   Вверх
VOS
Дата 30.11.2007, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 31.1.2007

Репутация: нет
Всего: 8



Похоже не поддерживает. 
Тогда во временную таблицу придется еще и идентификатор сессии втыкать, как в примере от
Deniz - ident = gen_id(..., 1);
 а потом delete from ... where ident=:ident
PM MAIL   Вверх
tishaishii
Дата 30.11.2007, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Создатель
***


Профиль
Группа: Завсегдатай
Сообщений: 1262
Регистрация: 14.2.2006
Где: Москва

Репутация: нет
Всего: 8



Временная таблица не нужна.
Нужно добавить в существующую поле ID_ORD.
И выполнить:
Код

OLD_ID_FIRM=NULL;
FOR
   SELECT ID_MSG, ID_FIRM FROM TABLE1 ORDER BY ID_FIRM INTO :ID_MSG, :ID_FIRM
DO BEGIN
   IF(:OLD_ID_FIRM<>:ID_FIRM) THEN
   BEGIN
      I=0;
      OLD_ID_FIRM=:ID_FIRM;
   END
   ELSE
      I=:I+1;
   UPDATE TABLE1 SET ID_ORD=:I WHERE ID_MSG=:ID_MSG;
END

Таким образом, массив отсортировали по коду агентства и записям каждого агентства присвоили число от 0 до ... Если при просмотре очередной записи, код агентства не совпадает с предыдущим кодом, то обнуляем счётчик и продолжаем нумеровать.

Потом можно выполнить простую выборку:
Код
SELECT ID_MSG, ID_FIRM FROM TABLE1 ORDER BY ID_ORD, ID_FIRM


Это сообщение отредактировал(а) tishaishii - 30.11.2007, 18:32
PM MAIL ICQ Skype   Вверх
tishaishii
Дата 30.11.2007, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Создатель
***


Профиль
Группа: Завсегдатай
Сообщений: 1262
Регистрация: 14.2.2006
Где: Москва

Репутация: нет
Всего: 8



Описание таблицы и процедуры предварительного упорядочивания.

Код
/******************************************************************************/
/***               Generated by IBExpert 30.11.2007 18:57:49                ***/
/******************************************************************************/

SET SQL DIALECT 3;

SET NAMES WIN1251;



/******************************************************************************/
/***                                 Tables                                 ***/
/******************************************************************************/



CREATE TABLE MSGS (
    ID_MSG   ID NOT NULL /* ID = BIGINT */,
    ID_FIRM  ID NOT NULL /* ID = BIGINT */,
    ID_ORD   ID /* ID = BIGINT */
);




/******************************************************************************/
/***                              Primary Keys                              ***/
/******************************************************************************/

ALTER TABLE MSGS ADD CONSTRAINT PK_MSGS PRIMARY KEY (ID_MSG);


/******************************************************************************/
/***                               Privileges                               ***/
/******************************************************************************/

SET TERM ^ ;

CREATE PROCEDURE ORD1 
AS
DECLARE VARIABLE OLD_ID_FIRM BIGINT;
DECLARE VARIABLE ID_FIRM BIGINT;
DECLARE VARIABLE ID_MSG BIGINT;
DECLARE VARIABLE I BIGINT;
begin
  OLD_ID_FIRM=NULL;
  I=0;
FOR
   SELECT ID_MSG, ID_FIRM FROM MSGS ORDER BY ID_FIRM INTO :ID_MSG, :ID_FIRM
DO BEGIN
   IF(:OLD_ID_FIRM=:ID_FIRM) THEN
      I=:I+1;
   ELSE
   BEGIN
      I=0;
      OLD_ID_FIRM=:ID_FIRM;
   END
   UPDATE MSGS SET ID_ORD=:I WHERE ID_MSG=:ID_MSG;
END
end
^

SET TERM ; ^

GRANT SELECT,UPDATE ON MSGS TO PROCEDURE ORD1;

GRANT EXECUTE ON PROCEDURE ORD1 TO SYSDBA;


Окончательная выборка.
Код

EXECUTE PROCEDURE ORD1;
SELECT ID_MSG, ID_FIRM FROM MSGS ORDER BY ID_ORD, ID_FIRM;

PM MAIL ICQ Skype   Вверх
Akella
Дата 30.11.2007, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



Всем ответившим большое спасибо!!! Но..... есть процедура, кусок которой я упомянул в первом сообщении, которую не получиться сильно изменить, т.к. алгоритм строг.

Код

CREATE OR ALTER PROCEDURE T_EXPORT_TO_PAGE_MAKER 
RETURNS (
    TAG VARCHAR(30),
    RUBRIKA VARCHAR(30),
    TEXT VARCHAR(1000),
    PHONE VARCHAR(100),
    ID_AGENCY1 BIGINT,
    ID1 BIGINT,
    VID_SO_EXP INTEGER)
AS
DECLARE VARIABLE CURRENTTYP VARCHAR(30) CHARACTER SET WIN1251 = '';
DECLARE VARIABLE CURRENTRAZ VARCHAR(30) CHARACTER SET WIN1251 = '';
DECLARE VARIABLE CURRENTRUB VARCHAR(30) CHARACTER SET WIN1251 = '';
DECLARE VARIABLE CURRENTNAP VARCHAR(30) CHARACTER SET WIN1251 = '';
DECLARE VARIABLE CURRENTREG VARCHAR(30) CHARACTER SET WIN1251 = '';
DECLARE VARIABLE ID BIGINT;
DECLARE VARIABLE TYPTYPE VARCHAR(30) CHARACTER SET WIN1251 = '';
DECLARE VARIABLE RAZTYPE VARCHAR(30) CHARACTER SET WIN1251 = '';
DECLARE VARIABLE RUBTYPE VARCHAR(30) CHARACTER SET WIN1251 = '';
DECLARE VARIABLE NAPTYPE VARCHAR(30) CHARACTER SET WIN1251 = '';
DECLARE VARIABLE REGTYPE VARCHAR(30) CHARACTER SET WIN1251 = '';
DECLARE VARIABLE OB_WEEK_DAY SMALLINT;
DECLARE VARIABLE CURRENT_WEEK_DAY SMALLINT;
begin

  CURRENT_WEEK_DAY = extract(weekday from current_date);


  for select ttype.name,
             trazdel.name,
             trubrika.name,
             tnapr.name,
             tregion.name,
             treklama.id,
             (select result from sp_is_objava_today(treklama.id))

      from ttype, trazdel, trubrika, tnapr, tregion, treklama, tvid
      where
        ttype.id    = treklama.id_type    and
        trazdel.id  = treklama.id_razdel  and
        trubrika.id = treklama.id_rubrika and
        tnapr.id    = treklama.id_napr    and
        tregion.id  = treklama.id_region  and
        tvid.id     = treklama.id_vid     and
        ((treklama.expiredate >= current_date) Or (treklama.expiredate is NULL))


  order by ttype.SO_EXP, trazdel.SO_EXP, trubrika.SO_EXP, tnapr.SO_EXP, tregion.SO_EXP, treklama.ID, tvid.SO_EXP--, treklama.ID_AGENCY
  into :TypType, :RAZTYPE, :RUBTYPE, :NAPTYPE, :REGTYPE, :ID, :OB_WEEK_DAY


  do begin
    -- set all fields into null
    TAG     = '';
    RUBRIKA = '';
    text    = '';
    phone   = '';

    if (CurrentTyp <> TypType) then begin
      CurrentTyp = TypType;
      CURRENTRAZ = '';
      CurrentRub = '';
      CURRENTNAP = '';
      CurrentReg = '';

      RUBRIKA = TypType;
      TAG = '<ТИП>';
      suspend;
    end--if

    if (CurrentRaz <> RazType) then begin
      CurrentRaz = RazType;
      CurrentRub = '';
      CURRENTNAP = '';
      CurrentReg = '';

      RUBRIKA = RazType;
      TAG = '<РАЗДЕЛ>';
      suspend;
    end--if

    if (CurrentRub <> RubType) then begin
      CurrentRub = RubType;
      CURRENTNAP = '';
      CurrentReg = '';

      RUBRIKA = RubType;
      TAG = '<РУБРИКА>';
      suspend;
    end--if

    if (CurrentNap <> NapType) then begin
      CurrentNap = NapType;
      CurrentReg = '';

      RUBRIKA = NapType;
      TAG = '<НАПРАВЛЕНИЕ>';
      suspend;
    end--if

    if (CurrentNap <> NapType) then begin
      CurrentNap = NapType;
      CurrentReg = '';

      RUBRIKA = NapType;
      TAG = '<НАПРАВЛЕНИЕ>';
      suspend;
    end--if

    if (CurrentReg <> RegType) then begin
      CurrentReg = RegType;

      RUBRIKA = RegType;
      TAG = '<РАЙОН>';
      suspend;
    end--if

    RUBRIKA = '';
    TAG     = '';

    select
           TVID.SO_EXP,
           TREKLAMA.ID_AGENCY,
           TREKLAMA.id,
           TVID.NAME,
           TREKLAMA.TEXT,
           TREKLAMA.PHONE


      from TREKLAMA, TVID /*, TTYPE, TRAZDEL, TRUBRIKA, TNAPR, TREGION*/

      where TREKLAMA.ID = :ID
      and   TVID.ID     = TREKLAMA.ID_VID

      GROUP by 1, 2, 3, 4, 5, 6

      into :VID_SO_EXP,
           :ID_AGENCY1,
           :ID1,
           :TAG,
           :TEXT,
           :PHONE

      ;

    suspend;
  end

end


Добавлено @ 23:27
я очень заинтересовавшимся могу базу отправить smile
процедура должна выбирать записи в определённом порядке:

вот объявления в газете как выводятся?

Цитата

жилая недвижимость
1 комн.
район Центр
  объявление1
  объявление2
  объявление3
  объявление4
район Вокзал
  объявление5
  объявление6
  объявление7
  объявление8
район Ивановка
  объявление9
  объявление10
  объявление11
  объявление12

2 комн.
район Центр
  объявление13
  объявление14
  объявление15
  объявление16
район Вокзал
  объявление17
  объявление18
  объявление19
  объявление20

Офисы 
.......
...



Добавлено @ 23:31
сейчас сначала идут объявления одного агентства, потом второго, потом третьего, так не справедливо вроде

вот то, что храниться в таблице
user posted image

вот то, как выводит процедура
user posted image
на этом рисунке неправильно, должно быть от каждого агентства поочереди по одному оъявлению

пока не знаю как решить 6(

Добавлено через 10 минут и 34 секунды
Цитата

фирма 1 - объява1
фирма 2 - объява1
фирма 1 - объява2
фирма 2 - объява2

типа по справедливости

Это сообщение отредактировал(а) Akella - 30.11.2007, 23:31
PM MAIL   Вверх
Deniz
Дата 1.12.2007, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 22
Всего: 44



Цитата(tishaishii @  30.11.2007,  21:32 Найти цитируемый пост)
Таким образом, массив отсортировали по коду агентства и записям каждого агентства присвоили число от 0 до ... 
все правильно, но ... если несколько пользователей одновременно запустят процедуру, причем по разным временным периодам, в лучшем случае они получат deadlock, в худшем некорректную выборку.
Говоря про временную таблицу имелось ввиду как раз дополнительная таблица, только я предлагал добавить в нее еще идентификатор выборки.

Akella, хочу помочь, но, честно говоря, лень читать все и разбираться.
Свое видение я рассказал, возможно будут какие-то дополнения.


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
Akella
Дата 3.12.2007, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



всем спасибо, буду разбираться

PM MAIL   Вверх
tishaishii
Дата 4.12.2007, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Создатель
***


Профиль
Группа: Завсегдатай
Сообщений: 1262
Регистрация: 14.2.2006
Где: Москва

Репутация: нет
Всего: 8



Цитата(Deniz @  1.12.2007,  12:55 Найти цитируемый пост)
все правильно, но ... если несколько пользователей одновременно запустят процедуру, причем по разным временным периодам, в лучшем случае они получат deadlock, в худшем некорректную выборку.
Говоря про временную таблицу имелось ввиду как раз дополнительная таблица, только я предлагал добавить в нее еще идентификатор выборки.


Ну ни кто не говорил про многих пользователей. Кроме того, я понял, что дело касается вёрстки газеты, а это, скорее всего, делает 1 человек и не часто.

Это сообщение отредактировал(а) tishaishii - 4.12.2007, 15:20
PM MAIL ICQ Skype   Вверх
Akella
Дата 4.12.2007, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



Цитата(tishaishii @  4.12.2007,  15:19 Найти цитируемый пост)
дело касается вёрстки газеты, а это, скорее всего, делает 1 человек и не часто.

да, 1 человек, в конце дня
PM MAIL   Вверх
Deniz
Дата 5.12.2007, 07:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 22
Всего: 44



OFF:
Цитата(tishaishii @  4.12.2007,  18:19 Найти цитируемый пост)
Ну ни кто не говорил про многих пользователей. Кроме того, я понял, что дело касается вёрстки газеты, а это, скорее всего, делает 1 человек и не часто.

Не помню как точно звучала фраза, но ...
Код

Закладывать в систему ограничение, что будет работать один пользователь - это закладывать мину себе под ж.... 
(с) не помню, кто-то уважаемый с www.sql.ru

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


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
Akella
Дата 5.12.2007, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



Я не сказал о том, что будет работать один пользователь!
PM MAIL   Вверх
Akella
Дата 20.12.2007, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



пока сделал так
Цитата(Deniz @  30.11.2007,  07:57 Найти цитируемый пост)
можно добавить в таблицу поле "№ объявления" и вести его по каждому агенству.


т.е. добавил поле ID2, где хранятся неуникальные ID, т.е. получается что-то вроде такого
ID общявления, ID агентства, ID объявления агентства

в конце сделал сортировку по этому полю, не совсем пока то, что хотелось, за то: минимум изменений структуры базы и нет изменений в исполняемом файле
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Interbase"
Alex

Обязательно указание:

1. Версию InterBase (Firebird, Yaffil)

2. Способа доступа (ADO, BDE, IBX и т.д.)

  • КАК ПРАВИЛЬНО ОФОРМИТЬ КОД - ЗДЕСЬ
  • КАК ПРАВИЛЬНО УКАЗАТЬ ТЕКСТ ОШИБКИ - ЗДЕСЬ
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • FAQ раздела лежит здесь!

Если Вам понравилась атмосфера форума, заходите к нам чаще! С Уважением, Akella.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Firebird, Interbase | Следующая тема »


 




[ Время генерации скрипта: 0.0636 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.