powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / разбивка диапазона на строки
4 сообщений из 4, страница 1 из 1
разбивка диапазона на строки
    #39032721
saoirse
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Вопрос следующий:

Есть таблица с данными, которая состоит из двух колонок. Улица и номер дома.
Но некоторые номера домов записаны диапазоном, например 11-21.
Каким образом можно разбить колонку Building, чтобы заполнились диапазоны номеров?
Вид исходной таблицы:
Street | Building
улица 1-я | 3
улица 2-я | 2-10 (четная сторона)
улица 3-я | 9-21 (нечетная сторона)
улица 4-я | 1-5 (четная + нечетная сторона)
улица 5-я | 9А-9В (адреса с буквами)


Что должно получиться на выходе:
Street | Building
улица 1-я | 3
улица 2-я | 2
улица 2-я | 4
улица 2-я | 6
улица 2-я | 8
улица 2-я | 10
улица 4-я | 1
улица 4-я | 2
улица 4-я | 3
улица 4-я | 4
улица 5-я | 9А
улица 5-я | 9Б
улица 5-я | 9В

и т.д.
...
Рейтинг: 0 / 0
разбивка диапазона на строки
    #39032821
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
saoirseДобрый день!
Есть таблица с данными, которая состоит из двух колонок. Улица и номер дома.
Но некоторые номера домов записаны диапазоном, например 11-21.
Каким образом можно разбить колонку Building, чтобы заполнились диапазоны номеров?
Вид исходной таблицы:


В общем случае никак - только ручками. :-)
А так можете некоторые явные диапазоны перенести с помощью запроса или скрипта.
...
Рейтинг: 0 / 0
разбивка диапазона на строки
    #39033200
vsl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
vsl
Гость
saoirseДобрый день!
Но некоторые номера домов записаны диапазоном, например 11-21.
Каким образом можно разбить колонку Building, чтобы заполнились диапазоны номеров?
Вид исходной таблицы:
Street | Building
улица 1-я | 3
улица 2-я | 2-10 (четная сторона)
улица 3-я | 9-21 (нечетная сторона)
улица 4-я | 1-5 (четная + нечетная сторона)
улица 5-я | 9А-9В (адреса с буквами)


Если у вас диапазоны действительно снабжены пометками, то см. ниже. Если нет, то как вы отличите диапазон от обычного номера дома? На здании, в котором я нахожусь в данную минуту, висит табличка "4-6". Домов №4 и №6 не существует уже больше ста лет.

Код: sql
1.
2.
3.
4.
5.
6.
create table test1 (street varchar(200), building varchar(200));
insert into test1(street, building) values ('улица 1-я', '3');
insert into test1(street, building) values ('улица 2-я', '2-10 (четная сторона)');
insert into test1(street, building) values ('улица 3-я', '9-21 (нечетная сторона)');
insert into test1(street, building) values ('улица 4-я', '1-5 (четная + нечетная сторона)');
insert into test1(street, building) values ('улица 5-я', '9А-9В (адреса с буквами)');



Код: 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.
with parsed as (
    select 
        street, 
        building, 
        type_, 
        case 
            when type_=4 then regexp_replace(building, '^([0-9]+)([А-Я])-[0-9]+([А-Я])$', '\1') 
            else null 
        end as basenum /* базовый номер дома*/,
        case type_ 
            when 0 then null 
            when 4 then regexp_replace(building, '^([0-9]+)([А-Я])-[0-9]+([А-Я])$', '\2') 
            else regexp_replace(building, '^([0-9]+)-([0-9]+)$', '\1') 
        end as lo_val /* нижняя граница диапазона */,
        case type_ 
            when 0 then null 
            when 4 then regexp_replace(building, '^([0-9]+)([А-Я])-[0-9]+([А-Я])$', '\3') 
            else regexp_replace(building, '^([0-9]+)-([0-9]+)$', '\2') 
        end as hi_val /* верхняя граница диапазона */
    from (
        select 
            street, 
            regexp_replace(building, '^(.*?)\s*\((.+)\)$', '\1') as building, 
            case regexp_replace(building, '^.*\((.+)\)$', '\1')
                when 'четная сторона' then 1
                when 'нечетная сторона' then 2
                when 'четная + нечетная сторона' then 3
                when 'адреса с буквами' then 4
                else 0
            end as type_ 
        from test1 
    ) t
)
select street, building from parsed where type_=0
union
select street, ''||generate_series(cast(lo_val as integer), cast(hi_val as integer), 2) from parsed where type_ in (1, 2)
union
select street, ''||generate_series(cast(lo_val as integer), cast(hi_val as integer)) from parsed where type_=3
union
select street, basenum||substr('АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ',x,1) from (
    select 
        street, 
        basenum, 
        generate_series(strpos('АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ', lo_val), strpos('АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ', hi_val)) x 
    from parsed 
    where 
        type_=4 
        and strpos('АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ', lo_val)>0 
        and strpos('АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ', hi_val)>strpos('АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ', lo_val)
) t
...
Рейтинг: 0 / 0
разбивка диапазона на строки
    #39035115
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно оформить set returning function, которая по входной строке домА (например '2-10 (четная сторона)') вычисляет и возвращает набор строк домов (например '2', '4', '8', '10'). И запрос из таблицы с использованием этой функции.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / разбивка диапазона на строки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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