powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как определить/получить диапазон
16 сообщений из 41, страница 2 из 2
Как определить/получить диапазон
    #39250336
stelvic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush, тогда арендовать :)
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39307511
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev,
Хочу поднять снова тему и немного уточнить
Та процедура, пример которой вы мне дали, если я разделю номера квартир на цифры и символы, выберет только диапазоны квартир без букв. А буквенные квартиры нужно прикрутить самостоятельно. ПРАВИЛЬНО???
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39307675
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если я правильно понял, то вопрос - возможно ли после выполнения процедуры добавить строчки с квартирами у которых в номере буквы. Как бы выполнить UNION.
Чтобы в результате работы процедуры у меня была готовая таблица для выгрузки.
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39308189
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush, вынесите буквенный постфикс квартиры в отдельное поле и соединяйте его с номером квартиры SELECT'ом в одно поле только если вам нужен информационный вывод этих данных вместе, а хранить в базе и работать над значениями этих полей надо раздельно.
При выборке диапазона квартир в предложении WHERE, поле буквенного постфикса не должно учитываться, т.к. оно несет исключительно информационный характер и стряпать по нему условие выборки нет резона.
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39308799
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devakrush, вынесите буквенный постфикс квартиры в отдельное поле и соединяйте его с номером квартиры SELECT'ом в одно поле только если вам нужен информационный вывод этих данных вместе, а хранить в базе и работать над значениями этих полей надо раздельно.
При выборке диапазона квартир в предложении WHERE, поле буквенного постфикса не должно учитываться, т.к. оно несет исключительно информационный характер и стряпать по нему условие выборки нет резона.

Изменил структуру таблицы. Разделил буквы отдельно, цифры отдельно.
теперь поле flat11 integer, flat12 varchar, и где нет буквы стоит null.
Теперь для того чтобы квартиры с буквами не участвовали в выборке диапазона мне нужно запрос в процедуре изменить на:
Код: sql
1.
2.
3.
4.
5.
SELECT v_cod, bld, Coalesce(corp, ''), taryf1, flat11
        FROM work_oplata
        where flat12 is null
        ORDER BY v_cod, bld, Coalesce(corp, ''), flat11
        INTO: nextStreetId, nextBldNum, nextBldLit, nextPrice, nextFlat



А уже потом сделать 2 селекта:
селект из процедуры
юнион
селект квартиры с буквами

я ПРАВИЛЬНО понимаю?
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39308994
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush, не понятно зачем выбирать квартиры без литер, а затем соединять с выборкой квартир с литерами. Если я правильно понимаю, тариф за квартиру с литерой может отличаться от тарифа за квартиру с тем же номером, но без литеры и поэтому их нельзя исключать из выборки.

Вот как-то так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
CREATE DOMAIN TARIFF AS NUMERIC(8,2)
  CHECK(VALUE >= 0);
CREATE DOMAIN BUILDING_LABEL AS VARCHAR(6)
  CHARACTER SET WIN1251
  COLLATE WIN1251_UA;
CREATE DOMAIN FLAT_LABEL AS VARCHAR(6)
  CHARACTER SET WIN1251
  COLLATE WIN1251_UA;   -- для корректного упорядочивания по ORDER BY
CREATE DOMAIN FLAT_NUMBER AS SMALLINT
  CHECK(VALUE >= 0);
CREATE DOMAIN FLAT_LITER AS CHAR(1)
  CHARACTER SET WIN1251
  COLLATE WIN1251_UA;


CREATE TABLE WORK_OPLATA
(
    NN      INTEGER NOT NULL,
    M_COD   INTEGER,
    VUL_N   VARCHAR(50) NOT NULL,
    V_COD   INTEGER NOT NULL,
    BLD     BUILDING_LABEL NOT NULL,
    CORP    BUILDING_LABEL DEFAULT NULL,
    FLAT11  FLAT_NUMBER NOT NULL,
    FLAT12  FLAT_LITER DEFAULT NULL,
    FLAT2   FLAT_LABEL,
    TARYF1  TARIFF,
    TARYF2  TARIFF
  CONSTRAINT WORK_OPLATA__PK PRIMARY KEY (NN),
  CONSTRAINT WORK_OPLATA__UQ UNIQUE (V_COD, BLD, CORP, FLAT11, FLAT12)
);


CREATE OR ALTER PROCEDURE price_ranges
  RETURNS
  (
    price        TARIFF,
    street_id    INTEGER,
    bld_num      VARCHAR(10) CHARACTER SET WIN1251,
    bld_lit      VARCHAR(10) CHARACTER SET WIN1251,
    flat_from    FLAT_LABEL,
    flat_to      FLAT_LABEL
  )
AS
  DECLARE VARIABLE nextPrice    TARIFF;
  DECLARE VARIABLE nextStreetId INTEGER DEFAULT NULL;
  DECLARE VARIABLE nextFlatNum  FLAT_NUMBER;
  DECLARE VARIABLE flatNumTo    FLAT_NUMBER;
  DECLARE VARIABLE nextFlatLit  FLAT_LITER;
  DECLARE VARIABLE flatLitTo    FLAT_LITER;
  DECLARE VARIABLE nextBldNum   BUILDING_LABEL;
  DECLARE VARIABLE nextBldLit   BUILDING_LABEL;
BEGIN
  FOR
      SELECT v_cod, bld, Coalesce(corp, ''), taryf1, flat11, flat12
        FROM work_oplata
        ORDER BY v_cod, bld, corp NULLS FIRST, flat11, flat12 NULLS FIRST
        INTO: nextStreetId, nextBldNum, nextBldLit, nextPrice,
              nextFlatNum, nextFlatLit
    DO
      BEGIN
        IF (:street_id IS NOT NULL) THEN
          BEGIN
            IF (:nextStreetId != :street_id
                OR :nextBldNum != :bld_num
                OR :nextBldLit != :bld_lit
                OR :nextPrice != :price
                OR :nextFlatNum - 1 - :flatNumTo > 0) THEN
              BEGIN
                flat_to = flatNumTo || Coalesce(flatLitTo, '');
                SUSPEND;
                flat_from = nextFlatNum || Coalesce(nextFlatLit, '');
              END
          END
        ELSE
          flat_from = nextFlatNum || Coalesce(nextFlatLit, '');
        flatNumTo = nextFlatNum;
        flatLitTo = nextFlatLit;
        price = nextPrice;
        street_id = nextStreetId;
        bld_num = nextBldNum;
        bld_lit = nextBldLit;
      END
  IF (:street_id IS NOT NULL) THEN SUSPEND;
END


...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39309181
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush, в конце процедуры надо заменить:
Код: plsql
1.
IF (:street_id IS NOT NULL) THEN SUSPEND;

на:
Код: plsql
1.
2.
3.
4.
5.
IF (:street_id IS NOT NULL) THEN
  BEGIN
    flat_to = flatNumTo || Coalesce(flatLitTo, '');
    SUSPEND;
  END
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39311127
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev,
Подскажите: если в БД у меня будет украинский язык, обязательно ли указывать при создании таблиц, как вы советовали в процедуре для order by,
CHARACTER SET WIN1251
COLLATE WIN1251_UA;
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39311140
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,

начиная с 2.5 для чарсетов можно поменять коллейт по умолчанию.


Код: sql
1.
2.
ALTER CHARACTER SET WIN1251
SET DEFAULT COLLATION WIN1251_UA;
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39311141
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush, если БД создавалась с указанием collation, то не обязательно.
К примеру:
Код: plsql
1.
2.
3.
4.
CREATE DATABASE ...
  DEFAULT CHARACTER SET WIN1251
  COLLATION WIN1251_UA
...
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39311142
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисakrush,

начиная с 2.5 для чарсетов можно поменять коллейт по умолчанию.


Код: sql
1.
2.
ALTER CHARACTER SET WIN1251
SET DEFAULT COLLATION WIN1251_UA;



У меня 2,5. подскажите где это сделать или как
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39311144
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,
Уже увидел. Спасибо.
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39311145
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,

просто выполни оператор. Но учти, что это повлияет на использование набора символов в будущем, кроме случаев, когда явно переопределена сортировка COLLATE. Сортировка существующих доменов, столбцов и переменных PSQL при этом не будет изменена.
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39311698
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrushесли в БД у меня будет украинский языкЕсли доп языков (помимо английского, куда ж без басурманского?) более одного, то стОит крепко подумать о юникоде (utf8).
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Как определить/получить диапазон
    #39727523
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет.
Дабы не плодить темы и так как процедура взята с этой темы, решил написать тут.
1. Таблица:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE TABLE APPLIC (
    BD        SMALLINT DEFAULT 0 NOT NULL CHECK (value >=0),        -- Номер БД
    APP_NUM   INTEGER DEFAULT 0 NOT NULL,                                   -- Номер дела
    CAL_NUM   SMALLINT DEFAULT 0 NOT NULL CHECK (value >=0),    -- Номер обращения. Последнее обращение ВСЕГДА =0
    CAL_LAST  SMALLINT DEFAULT 0 NOT NULL CHECK (value >=0),    -- Номер предыдущего обращения
    DATA_S    DATE,                                            -- дата начала действия обращения, всегда 1 число месяца
    DATA_E    DATE,                                            -- дата окончания действия, всегда последнее число месяца
    DATA_X    DATE);                                          -- дата досрочной остановки обращения
ALTER TABLE APPLIC ADD CONSTRAINT PK_APPLIC PRIMARY KEY (BD, APP_NUM, CAL_NUM);



2. Процедура:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
create or alter procedure RANGES_DATAS
returns (
    BD smallint,
    APP_NUM integer,
    DATA_FROM date,
    DATA_TO date)
AS
declare variable L_APP_NUM integer;
declare variable L_DATA_FROM date;
declare variable L_DATA_TO date;
declare variable L_DATA_X date;
declare variable L_DATA_X_PREV date;
begin
  for select BD, APP_NUM, DATA_S, DATA_E, DATA_X
      from APPLIC
      order by BD, APP_NUM, DATA_S, DATA_E, DATA_X
      into BD, :L_APP_NUM, L_DATA_FROM, L_DATA_TO, L_DATA_X
  do
  begin
    if (L_DATA_FROM <> L_DATA_X_PREV) then
    begin
      suspend;
      APP_NUM = 0;
    end
    if (APP_NUM <> 0) then
    begin
      if (APP_NUM != :L_APP_NUM) then
      begin
        suspend;
        APP_NUM = :L_APP_NUM;
        if (:L_DATA_X is not null) then
        begin
            DATA_TO = :L_DATA_X - 1;
          L_DATA_X_PREV = :L_DATA_X;
        end
        else
        begin
            DATA_TO = :L_DATA_TO;
        end
        DATA_FROM = :L_DATA_FROM;
      end
    end
    else
    begin
      APP_NUM = :L_APP_NUM;
      DATA_FROM = :L_DATA_FROM;
    end
    if (:L_DATA_X is not null) then
    begin
        DATA_TO = :L_DATA_X - 1;
      L_DATA_X_PREV = :L_DATA_X;
    end
    else
    begin
        DATA_TO = :L_DATA_TO;
    end
  end
  if (:APP_NUM is not null) then
  begin
    if (:L_DATA_X is not null) then
    begin
        DATA_TO = :L_DATA_X - 1;
      L_DATA_X_PREV = :L_DATA_X;
    end
    else
    begin
        DATA_TO = :L_DATA_TO;
    end
    suspend;
  end
end



Прикрепляю файл данными созданный IBExpert скрипт на добавление записей (Insert)

Пояснения к данным что касается полей ДАТА
DATA_X - дата досрочной остановки (пользователь не видит этой даты). В случае повторного обращения в период действия DATA_X=DATA_S(повторного обращения).
В случае если установлена DATA_X, то DATA_E надо отображать как DATA_X-1.
На примере одного дела покажу что есть и что надо получить:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Исходные данные:
BD	CAL_NUM	APP_NUM	CAL_LAST	DATA_S	DATA_E	DATA_X
1	90	1	89	01.01.2018	30.04.2018	01.02.2018
1	91	1	90	01.02.2018	30.04.2018	01.03.2018
1	92	1	91	01.04.2018	30.04.2018	01.05.2018
1	93	1	92	01.05.2018	30.09.2018	01.06.2018
1	0	1	93	01.08.2018	30.09.2018	

Результат работы процедуры:
BD	APP_NUM	DATA_S	DATA_E
1	1	01.01.2018	29.02.2018
1	1	01.04.2018	31.05.2018
1	1	01.08.2018	30.09.2018	



Хочу получить совет возможно ли оптимизировать код процедуры т.к. процедура взята с этой темы и просто допилена напильником "чтоб работало".
Был еще второй вопрос, но пока его писал понял как его решить :)
...
Рейтинг: 0 / 0
Как определить/получить диапазон
    #39727524
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл написать изменения как решил свой вопрос.
Администраторы, можно ли заменить одну строку в моем сообщении.
В процедуре в селекте order by должен быть таким:

order by BD, APP_NUM, cal_last
...
Рейтинг: 0 / 0
16 сообщений из 41, страница 2 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как определить/получить диапазон
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]