Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在语言相关数据的PostgreSQL中实现分层查询_Postgresql_Hierarchical Data_Recursive Query_Postgresql 12_Collate - Fatal编程技术网

如何在语言相关数据的PostgreSQL中实现分层查询

如何在语言相关数据的PostgreSQL中实现分层查询,postgresql,hierarchical-data,recursive-query,postgresql-12,collate,Postgresql,Hierarchical Data,Recursive Query,Postgresql 12,Collate,我试图从自动引用表上的查询中检索分层有序结果,如下所示: 创建表类别 id序列号, -父类别, 父\u id整数默认为null,根类别为-null -树木控制 树\u深度smallint不为null,-已计算 主键id, 唯一的父项id,id, 外键父项id引用类别id ; 除了需要支持多种语言外,这是存储类别树的常用方法。为此,我们加入了一个与语言相关的表,如下所示: 创建表类别 id序列号, -自然主键 类别id整数不为空, 语言代码char2不为空, -语言相关数据 标题varchar12

我试图从自动引用表上的查询中检索分层有序结果,如下所示:

创建表类别 id序列号, -父类别, 父\u id整数默认为null,根类别为-null -树木控制 树\u深度smallint不为null,-已计算 主键id, 唯一的父项id,id, 外键父项id引用类别id ; 除了需要支持多种语言外,这是存储类别树的常用方法。为此,我们加入了一个与语言相关的表,如下所示:

创建表类别 id序列号, -自然主键 类别id整数不为空, 语言代码char2不为空, -语言相关数据 标题varchar128不为空, 主键id, 唯一类别标识、语言代码 ; 在插入前触发器中计算tree_depth列,如下所示:

创建或替换函数fn\u category\u bins将触发器返回为$$ 开始 -将树深度计算为父树深度+1 如果new.parent_id为空,则 new.tree_depth=0; 其他的 new.tree\u depth=从类别中选择tree\u depth,其中id=new.parent\u id limit 1+1; 如果结束; 归还新的; 终止 $$语言plpgsql; 在为每行插入类别之前,创建触发器tg_类别_uu容器 执行程序fn_分类__bin; 我们用两种语言的易读文本填充表格:

在类别中插入父\u id,id值 空,1, 空,2, 空,3, 1, 11, 1, 12, 1, 13, 2, 21, 2, 22, 3, 31, 21, 211, 21, 212, 21, 213; -语言代码='EN' 插入类别\u语言类别\u id、标题、语言代码值 1、‘一’、‘恩’, 二,"二","恩",, 三,"三","恩",, 11、‘一、一’、‘恩’, 12、‘一、二’、‘恩’, 13、‘一、三’、‘恩’, 21、‘2.1’、‘EN’, 22,'2.2,'EN', 31、‘三、一’、‘恩’, 211,“二,一,一”,“恩”, 212,'2.1.2,'EN', 213,‘二。一。三’‘恩’; -语言代码='ES' 插入类别\u语言类别\u id、标题、语言代码值 1、‘Uno’、‘ES’, 2、‘Dos’、‘ES’, 3、‘Tres’、‘ES’, 11、‘Uno.Uno’、‘ES’, 12、‘Uno.Dos’、‘ES’, 13、‘Uno.Tres’、‘ES’, 21、‘Dos.Uno’、‘ES’, 22、‘Dos.Dos’、‘ES’, 31、'Tres.Uno'、'ES', 211,“Dos.Uno.Uno”,“ES”, 212,“Dos.Uno.Dos”,“ES”, 213,'Dos.Uno.Tres','ES'; 普通查询会产生如下自然结果:

从类别tc中选择* 左外连接category_lang tl on tl.category_id=tc.id和tl.lang_code='EN'; id |父| id |树|深度| id |类别| id |语言|代码|标题| --|-----|-----|-|------|-----|-------| 1 | 0 | 1 | 1 | EN | One| 2 | 0 | 2 | 2 | EN | 2| 3 | 0 | 3 | 3 | EN | 3| 11 | 1 | 1 | 4 | 11 | EN | One| 12 | 1 | 1 | 5 | 12 | EN | 1.2| 13 | 1 | 1 | 6 | 13 | EN | 1.3| 21 | 2 | 1 | 7 | 21 | EN | 2.1| 22 | 2 | 1 | 8 | 22 | EN | 2.2| 31 | 3 | 1 | 9 | 31 | EN | 3.1| 211 | 21 | 2 | 10 | 211 | EN | 2.1.1| 212 | 21 | 2 | 11 | 212 | EN | 2.1.2| 213 | 21 | 2 | 12 | 213 | EN | 2.1.3| 当预期的顺序应符合每个深度级别的树层次结构和英文字母顺序时,如下所示: [编辑以修复Erwin识别的错误]

id |父| id |树|深度| id |类别| id |语言|代码|标题| --|-----|-----|-|------|-----|-------| 1 | 0 | 1 | 1 | EN | One| 11 | 1 | 1 | 4 | 11 | EN | One| 13 | 1 | 1 | 6 | 13 | EN | 1.3| 12 | 1 | 1 | 5 | 12 | EN | 1.2| 3 | 0 | 3 | 3 | EN | 3| 31 | 3 | 1 | 9 | 31 | EN | 3.1| 2 | 0 | 2 | 2 | EN | 2| 21 | 2 | 1 | 7 | 21 | EN | 2.1| 211 | 21 | 2 | 10 | 211 | EN | 2.1.1| 213 | 21 | 2 | 12 | 213 | EN | 2.1.3| 212 | 21 | 2 | 11 | 212 | EN | 2.1.2| 22 | 2 | 1 | 8 | 22 | EN | 2.2| 请注意,每个深度的字母顺序强制西班牙语产生不同的结果: [编辑以修复Erwin识别的错误]

id |父| id |树|深度| id |类别| id |语言|代码|标题| --|-----|-----|-|------|-----|------| 2 | 0 | 14 | 2 | ES | Dos| 22 | 2 | 1 | 20 | 22 | ES | Dos.Dos| 21 | 2 | 1 | 19 | 21 | ES | Dos.Uno| 212 | 21 | 2 | 23 | 212 | ES | Dos.Uno.Dos| 213| 21| 2|24| |2 | EN | 2| 21 | 2 | 1 | 7 | 21 | EN | 2.1| 211 | 21 | 2 | 10 | 211 | EN | 2.1.1| 213 | 21 | 2 | 12 | 213 | EN | 2.1.3| 212 | 21 | 2 | 11 | 212 | EN | 2.1.2| 22 | 2 | 1 | 8 | 22 | EN | 2.2| 3 | 0 | 3 | 3 | EN | 3| 31 | 3 | 1 | 9 | 31 | EN | 3.1| 选择* 从列表目录树0中,“ES”作为tc tl.category_lang tl在tl.category_id=tc.id和tl.lang_code='ES'上的联接; id |父| id |树|深度| id |类别| id |语言|代码|标题| --|-----|-----|-|------|-----|------| 2 | 0 | 1 | 14 | 2 | ES | Dos| 22 | 2 | 2 | 20 | 22 | ES | Dos.Dos| 21 | 2 | 2 | 19 | 21 | ES | Dos.Uno| 212 | 21 | 3 | 23 | 212 | ES | Dos.Uno.Dos| 213 | 21 | 3 | 24 | 213 | ES | Dos.Uno.Tres| 211 | 21 | 3 | 22 | 211 | ES | Dos.Uno.Uno| 3 | 0 | 1 | 15 | 3 | ES | Tres| 31 | 3 | 2 | 21 | 31 | ES | Tres.Uno| 1 | 0 | 1 | 13 | 1 | ES | Uno| 12 | 1 | 2 | 17 | 12 | ES | Uno.Dos| 13 | 1 | 2 | 18 | 13 | ES | Uno.Tres| 11 | 1 | 2 | 16 | 11 | ES | Uno.Uno| 已将根节点作为

插入到\u类别的父\u id,id值中 null,0, 空,1, 空,2, 空,3, 1, 11, 1, 12, 1, 13, 2, 21, 2, 22, 3, 31, 21, 211, 21, 212, 21, 213; -语言代码='EN' 插入类别名称、名称、语言代码值 0,'根','EN', 1、‘一’、‘恩’, 二,"二","恩",, 三,"三","恩",, 11、‘一、一’、‘恩’, 12、‘一、二’、‘恩’, 13、‘一、三’、‘恩’, 21、‘2.1’、‘EN’, 22,'2.2,'EN', 31、‘三、一’、‘恩’, 211,“二,一,一”,“恩”, 212,'2.1.2,'EN', 213,‘二。一。三’‘恩’; -语言代码='ES' 插入类别名称、名称、语言代码值 0、'Raíz'、'ES', 1、‘Uno’、‘ES’, 2、‘Dos’、‘ES’, 3、‘Tres’、‘ES’, 11、‘Uno.Uno’、‘ES’, 12、‘Uno.Dos’、‘ES’, 13、‘Uno.Tres’、‘ES’, 21、‘Dos.Uno’、‘ES’, 22、‘Dos.Dos’、‘ES’, 31、'Tres.Uno'、'ES', 211,“Dos.Uno.Uno”,“ES”, 212,“Dos.Uno.Dos”,“ES”, 213,'Dos.Uno.Tres','ES';
在最终结果中,您希望EN和ES的顺序不同吗?我这样问是因为最终结果上的order by决定了排序。是的,正如我提到的,最终结果必须按层次和字母顺序排列,即图形决定主顺序,标题顺序决定给定树深度的顺序。请尝试按leftcategory_id::text,1,title.wow排序!这几乎是完美的!在tl.category\U id=tc.id和tl.lang\U code='EN'顺序上,按lefttl.category\U id::text,1,tl.titleUnfortute选择*从tl.category\U lang tl的左外部联接。第一级失败,返回1,2,3,而不是1,3,2。谢谢Erwin。所有这些都是很好的建议。是的,英国订单是我的错。我是手工做的,可能没有注意到两个字母中的“w”。@coterobarros:还要注意添加的关于排序的段落。哇,比我从一个简陋的分类树中期望的要多得多!我在数据库的其他不同部分遇到了collate问题,但这是解决这些问题的一个很好的起点。非常感谢。您关于文本的提示似乎与PostgreSQL中的提示冲突。查恩显然是一个糟糕的选举,但似乎在瓦尔查和文本之间没有区别。只要varchar的长度小于126个字符,我就使用它。关于有效大小,请参阅:
CREATE TYPE title_id AS (title varchar(128), id int);
 , FOREIGN KEY (category_id) REFERENCES category (id)