如何确定范围列表是否包含指定的整数

发布于 2025-02-01 18:38:26 字数 814 浏览 1 评论 0 原文

产品类型表包含产品类型。可能会丢失一些ID:

create table artliik (liiginrlki char(3) primary key);
insert into artliik values('1');
insert into artliik values('3');
insert into artliik values('4');
...
insert into artliik values('999');

属性表Contais Comma分离的类型列表。

create table strings ( id char(100) primary key, kirjeldLku chr(200) );
insert into strings values ('item1', '1,4-5' );
insert into strings values ('item2', '1,2,3,6-9,23-44,45' );

类型可以指定为单个整数,等式1,2,3或范围6-9或23-44 列表可以包含两个。

如何用于给定类型的所有属性。 查询

select id 
from artliik
join strings on ','||trim(strings.kirjeldLku)||',' like '%,'||trim(artliik.liiginrlki)||',%' 

单个整数列表的返回日期。 如何更改加入加入,以便返回列表中的该类型范围,也可以返回6-9的范围? 等式。 F列表包含报告中包含的6-9,6,7,8和9 shoud。

使用Postgres 13。

Product type table contains product types. Some ids may missing :

create table artliik (liiginrlki char(3) primary key);
insert into artliik values('1');
insert into artliik values('3');
insert into artliik values('4');
...
insert into artliik values('999');

Property table contais comma separated list of types.

create table strings ( id char(100) primary key, kirjeldLku chr(200) );
insert into strings values ('item1', '1,4-5' );
insert into strings values ('item2', '1,2,3,6-9,23-44,45' );

Type can specified as single integer, e.q 1,2,3 or as range like 6-9 or 23-44
List can contain both of them.

How to all properties for given type.
Query

select id 
from artliik
join strings on ','||trim(strings.kirjeldLku)||',' like '%,'||trim(artliik.liiginrlki)||',%' 

returns date for single integer list only.
How to change join so that type ranges in list like 6-9 are also returned?
Eq. f list contains 6-9, Type 6,7,8 and 9 shoud included in report.

Postgres 13 is used.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晨与橙与城 2025-02-08 18:38:26

我建议使用类似于 Un -nest 的辅助功能,以纪念范围。

校正函数

create or replace function unnest_ranges(s text)
returns setof text language sql immutable as
$
 with t(x) as (select unnest(string_to_array(s, ',')))
 select generate_series
 (
   split_part(x, '-', 1)::int, 
   case when x ~ '-' then split_part(x, '-', 2)::int else x::int end,
   1
 )::text
 from t;
$;

然后您可以'归一化'表字符串并加入。

select * 
from artliik a 
join (select id, unnest_ranges(kirjeldLku) from strings) as t(id, v)
on a.liiginrlki = v;

函数定义的使用当然是可选的。我更喜欢它,因为该功能是通用和可重复使用的。

I would suggest a helper function similar to unnest that honors ranges.

Corrected function

create or replace function unnest_ranges(s text)
returns setof text language sql immutable as
$
 with t(x) as (select unnest(string_to_array(s, ',')))
 select generate_series
 (
   split_part(x, '-', 1)::int, 
   case when x ~ '-' then split_part(x, '-', 2)::int else x::int end,
   1
 )::text
 from t;
$;

Then you can 'normalize' table strings and join.

select * 
from artliik a 
join (select id, unnest_ranges(kirjeldLku) from strings) as t(id, v)
on a.liiginrlki = v;

The use of a function definition is of course optional. I prefer it because the function is generic and reusable.

无敌元气妹 2025-02-08 18:38:26


COLATION DOC:
https://www.postgresql.org.org.org/docsql.org/docs/current/current/collent/collent/collat​​ion.html.


想法:创建一个多级文本数据类型,该数据类型将根据其数值值对数字值进行排序。像“ A-21”< 'A-123'。

CREATE COLLATION testcoll_numeric (
    provider = icu,
    locale = '@colNumeric=yes'
);

CREATE TYPE textrange AS RANGE (
    subtype = text,
    multirange_type_name = mulitrange_of_text,
    COLLATION = testcoll_numeric
);

因此,

SELECT
    mulitrange_of_text (textrange ('1'::text, '11'::text)) @> '9'::text AS contain_9;

应返回 true

Artliik表结构保持不变,但是Strings表需要更改。

CREATE temp TABLE strings (
    id text PRIMARY KEY,
    kirjeldLku mulitrange_of_text
);

然后查询它:

SELECT DISTINCT
    strings.id
FROM
    artliik,
    strings
WHERE
    strings.kirjeldLku @> liiginrlki::text
ORDER BY
    1;

dbfiddle.uk demo will only works on pg14, since only pg14 have multirange data type. But customizeable icu collation works in pg13.
Collation doc: https://www.postgresql.org/docs/current/collation.html


Idea: create a multirange text data type that will sort numeric value based on their numerical value. like 'A-21' < 'A-123'.

CREATE COLLATION testcoll_numeric (
    provider = icu,
    locale = '@colNumeric=yes'
);

CREATE TYPE textrange AS RANGE (
    subtype = text,
    multirange_type_name = mulitrange_of_text,
    COLLATION = testcoll_numeric
);

So

SELECT
    mulitrange_of_text (textrange ('1'::text, '11'::text)) @> '9'::text AS contain_9;

should return true.

artliik table structure remain the same, but strings table need to change a bit.

CREATE temp TABLE strings (
    id text PRIMARY KEY,
    kirjeldLku mulitrange_of_text
);

then query it:

SELECT DISTINCT
    strings.id
FROM
    artliik,
    strings
WHERE
    strings.kirjeldLku @> liiginrlki::text
ORDER BY
    1;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文