Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/82.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 9.3->来自嵌套集的JSON->jQuery listview_Jquery_Json_Postgresql - Fatal编程技术网

PostgreSQL 9.3->来自嵌套集的JSON->jQuery listview

PostgreSQL 9.3->来自嵌套集的JSON->jQuery listview,jquery,json,postgresql,Jquery,Json,Postgresql,我有这个嵌套集: id;parent;name;lft;rgt ---------------------- 1;0;"Food";2;21 3;1;"Appetizer";3;8 8;3;"Nachos & salsa";4;5 9;3;"Kentucky chicken wings";6;7 4;1;"Soup";9;14 10;4;"Broth";10;11 11;4;"Tomato soup";12;13 5;1;"Pizza";15;20 12;5;"Americana";16

我有这个嵌套集:

id;parent;name;lft;rgt
----------------------
1;0;"Food";2;21
3;1;"Appetizer";3;8
8;3;"Nachos & salsa";4;5
9;3;"Kentucky chicken wings";6;7
4;1;"Soup";9;14
10;4;"Broth";10;11
11;4;"Tomato soup";12;13
5;1;"Pizza";15;20
12;5;"Americana";16;17
13;5;"Margherita";18;19
2;0;"Beverages";22;27
6;2;"Wines";23;24
7;2;"Soft drinks";25;26
我想要一个代表完整树的JSON输出。 我想从JSON构建一个嵌套列表,如下所示:
谢谢你的帮助

要做的第一件事是以可以检索树的方式查询行。为此,我们可以简单地使用递归查询。假设您的表名为food,下面的查询是一个很好的递归查询示例:

WITH RECURSIVE t AS (
    SELECT f.id, f.name, f.parent, f.lft, f.rgt, array[f.name] AS path, 0 AS level
    FROM food f
    WHERE f.parent = 0
    UNION ALL
    SELECT f.id, f.name, f.parent, f.lft, f.rgt, t.path || f.name, level+1
    FROM food f JOIN t ON f.parent = t.id
)
SELECT repeat('|__', level)||t.name AS tree, level, path
FROM t
ORDER BY path;
将以以下形式返回:

             tree             | level |                   path                    
------------------------------+-------+-------------------------------------------
 Beverages                    |     0 | {Beverages}
 |__Soft drinks               |     1 | {Beverages,"Soft drinks"}
 |__Wines                     |     1 | {Beverages,Wines}
 Food                         |     0 | {Food}
 |__Appetizer                 |     1 | {Food,Appetizer}
 |__|__Kentucky chicken wings |     2 | {Food,Appetizer,"Kentucky chicken wings"}
 |__|__Nachos & salsa         |     2 | {Food,Appetizer,"Nachos & salsa"}
 |__Pizza                     |     1 | {Food,Pizza}
 |__|__Americana              |     2 | {Food,Pizza,Americana}
 |__|__Margherita             |     2 | {Food,Pizza,Margherita}
 |__Soup                      |     1 | {Food,Soup}
 |__|__Broth                  |     2 | {Food,Soup,Broth}
 |__|__Tomato soup            |     2 | {Food,Soup,"Tomato soup"}
(13 rows)
基本上,path数组将给我们一个元素来对行进行排序,这样我们就可以根据需要使用除名称以外的其他列的树,而level基本上是path length-1,它为我们提供了元素所在的级别。有了这两个信息,我们可以使用with窗口ORDER BY path的一些技巧,在每一行查看下一行的级别,从而创建json检查查询中的注释:

WITH RECURSIVE t AS (
    SELECT f.id, f.name, f.parent, f.lft, f.rgt, array[f.name] AS path, 0 AS level
    FROM food f
    WHERE f.parent = 0
    UNION ALL
    SELECT f.id, f.name, f.parent, f.lft, f.rgt, t.path || f.name, level+1
    FROM food f JOIN t ON f.parent = t.id
)
SELECT (E'[\n'||string_agg(json, E'\n')||E'\n]')::json FROM (
SELECT
    /* Add some simple indentation (why not?) */
    repeat('    ', level)
    || '{"name":'||to_json(name)|| ', "items":['
    ||
    /* The expr bellow will return the level of next row, or -1 if it is last */
    CASE coalesce(lead(level) OVER(ORDER BY path), -1)
        /* Next row opens a new level, so let's add the items array */
        WHEN level+1 THEN ''
        /* WHEN level+1 THEN ', "items":[' */
        /* We are on the same level, so just close the current element */
        WHEN level THEN ']},'
        /* Last row, close the current element and all other levels still opened (no indentation here, sorry) */
        WHEN -1 THEN ']}' || repeat(']}', level)
        /* ELSE, the next one belongs to another parent, just close me and my parent */
        ELSE /* closes me: */ ']}' /* closes my parent: */ || E'\n'||repeat('    ', level-1)||']},'
    END AS json
FROM t
) s1;
这将为我们提供以下json:

[
{"name":"Beverages", "items":[
    {"name":"Soft drinks", "items":[]},
    {"name":"Wines", "items":[]}
]},
{"name":"Food", "items":[
    {"name":"Appetizer", "items":[
        {"name":"Kentucky chicken wings", "items":[]},
        {"name":"Nachos & salsa", "items":[]}
    ]},
    {"name":"Pizza", "items":[
        {"name":"Americana", "items":[]},
        {"name":"Margherita", "items":[]}
    ]},
    {"name":"Soup", "items":[
        {"name":"Broth", "items":[]},
        {"name":"Tomato soup", "items":[]}]}]}
]

这是一个有点诡计的查询,我希望注释会有所帮助,也希望它对任何测试用例都是正确的。

对不起,但是我在使用下一个结构时遇到了一些问题

1,0,'Food',2,21
2,0,'Beverages',22,27
3,1,'Appetizer',3,8 
4,3,'Soup',9,14                   -- Parent soup is 3 instead 1
5,1,'Pizza',15,20
6,2,'Wines',23,24
7,2,'Soft drinks',25,26
8,3,'Nachos & salsa',4,5
9,3,'Kentucky chicken wings',6,7
10,4,'Broth',10,11
11,4,'Tomato soup',12,13
12,5,'Americana',16,17
13,5,'Margherita',18,19
结果:

             tree             | level |                   path                    
------------------------------+-------+-------------------------------------------
 Beverages                    |     0 | {Beverages}
 |__Soft drinks               |     1 | {Beverages,"Soft drinks"}
 |__Wines                     |     1 | {Beverages,Wines}
 Food                         |     0 | {Food}
 |__Appetizer                 |     1 | {Food,Appetizer}
 |__|__Kentucky chicken wings |     2 | {Food,Appetizer,"Kentucky chicken wings"}
 |__|__Nachos & salsa         |     2 | {Food,Appetizer,"Nachos & salsa"}
 |__|__Soup                   |     2 | {Food,Appetizer,Soup}
 |__|__|__Broth               |     2 | {Food,Appetizer,Soup,Broth}
 |__|__|__Tomato soup         |     3 | {Food,Appetizer,Soup,"Tomato soup"}
 |__Pizza                     |     1 | {Food,Pizza}
 |__|__Americana              |     2 | {Food,Pizza,Americana}
 |__|__Margherita             |     2 | {Food,Pizza,Margherita}
(13 rows)
使用相同的逻辑,这可能会更好:

WITH RECURSIVE t AS (
    SELECT f.id, f.name, f.parent, f.lft, f.rgt, array[f.name] AS path, 0 AS level
    FROM food f
    WHERE f.parent = 0
    UNION ALL
    SELECT f.id, f.name, f.parent, f.lft, f.rgt, t.path || f.name, level+1
    FROM food f JOIN t ON f.parent = t.id
) 
SELECT ( '[' || string_agg( json, '' ) || ']' ) :: json FROM (
select
    '{"name":'||to_json( name ) || 
    case lead( level, 1 ) OVER( ORDER BY path )
        when level then '},' --same lavel, no children, only close
        when level + 1 THEN ', "items":[' -- There's children, add item array
        else -- last child in group start to close
            '}' || --close actual element
            case
                when lead( level ) OVER( ORDER BY path ) < level THEN -- last children in group, close parents, until next level
                    repeat( ']}', level - lead( level ) OVER( ORDER BY path ) ) || ',' 
                else repeat( ']}', level ) -- last element in list, close parents all levels
            end
    end as json
from t
) s1;
压痕???也许以后

编辑 加小提琴

谢谢,我对查询做了一点修改,[]不需要,可以正常工作。