@@ -902,8 +902,8 @@ INSERT INTO my_films VALUES (
902
902
"director" : "Alfred Hitchcock" } ] },
903
903
{ "kind" : "thriller", "films" : [
904
904
{ "title" : "Vertigo",
905
- "director" : "Hitchcock" } ] },
906
- { "films" : [
905
+ "director" : "Alfred Hitchcock" } ] },
906
+ { "kind" : "drama", " films" : [
907
907
{ "title" : "Yojimbo",
908
908
"director" : "Akira Kurosawa" } ] }
909
909
] }');
@@ -1339,7 +1339,7 @@ SELECT
1339
1339
FROM my_films;
1340
1340
json_query
1341
1341
------------
1342
- ["comedy", "horror", "thriller"]
1342
+ ["comedy", "horror", "thriller", "drama" ]
1343
1343
(1 row)
1344
1344
1345
1345
@@ -1402,7 +1402,7 @@ SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text OMIT QUOTES);
1402
1402
1403
1403
1404
1404
JSON_TABLE (
1405
- json_api_common_syntax [ AS json_path_name ]
1405
+ json_api_common_syntax [ AS path_name ]
1406
1406
COLUMNS ( json_table_column [, ...] )
1407
1407
[ PLAN ( json_table_plan ) |
1408
1408
PLAN DEFAULT ( { INNER | OUTER } [ , { CROSS | UNION } ]
@@ -1412,30 +1412,29 @@ JSON_TABLE (
1412
1412
1413
1413
where json_table_column is:
1414
1414
1415
- { name type [ PATH json_path_specification ]
1416
- [ { ERROR | NULL | DEFAULT expression } ON EMPTY ]
1417
- [ { ERROR | NULL | DEFAULT expression } ON ERROR ]
1418
- | name type FORMAT json_representation
1419
- [ PATH json_path_specification ]
1420
- [ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } }
1421
- [ ARRAY ] WRAPPER ]
1422
- [ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ]
1423
- [ { ERROR | NULL | EMPTY { ARRAY | OBJECT } } ON EMPTY ]
1424
- [ { ERROR | NULL | EMPTY { ARRAY | OBJECT } } ON ERROR ]
1425
- | NESTED PATH json_path_specification [ AS path_name ]
1426
- COLUMNS ( json_table_column [, ...] )
1427
- | name FOR ORDINALITY }
1415
+ name type [ PATH json_path_specification ]
1416
+ [ { ERROR | NULL | DEFAULT expression } ON EMPTY ]
1417
+ [ { ERROR | NULL | DEFAULT expression } ON ERROR ]
1418
+ | name type FORMAT json_representation
1419
+ [ PATH json_path_specification ]
1420
+ [ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } }
1421
+ [ ARRAY ] WRAPPER ]
1422
+ [ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ]
1423
+ [ { ERROR | NULL | EMPTY { ARRAY | OBJECT } } ON EMPTY ]
1424
+ [ { ERROR | NULL | EMPTY { ARRAY | OBJECT } } ON ERROR ]
1425
+ | NESTED PATH json_path_specification [ AS path_name ]
1426
+ COLUMNS ( json_table_column [, ...] )
1427
+ | name FOR ORDINALITY
1428
1428
1429
1429
json_table_plan is:
1430
1430
1431
- path_name { OUTER | INNER | CROSS | UNION }
1432
- { path_name | ( nested_plan ) }
1431
+ path_name [ { OUTER | INNER } json_table_plan_primary ]
1432
+ | json_table_plan_primary { UNION json_table_plan_primary } [...]
1433
+ | json_table_plan_primary { CROSS json_table_plan_primary } [...]
1433
1434
1434
- nested_plan is:
1435
+ json_table_plan_primary is:
1435
1436
1436
- path_name { OUTER | INNER } { path_name | ( nested_plan ) }
1437
- | { path_name | ( nested_plan ) }
1438
- { { UNION | CROSS } { path_name | ( nested_plan ) } }[...]
1437
+ path_name | ( json_table_plan )
1439
1438
1440
1439
1441
1440
@@ -1453,9 +1452,9 @@ where json_table_column is:
1453
1452
1454
1453
1455
1454
Taking JSON data as input, JSON_TABLE uses
1456
- a path expression to extract a part of the provided input that
1455
+ a path expression to extract a part of the provided data that
1457
1456
will be used as a row pattern for the
1458
- contructed view. Each SQL/JSON item at the top level of the row pattern serves
1457
+ constructed view. Each SQL/JSON item at the top level of the row pattern serves
1459
1458
as the source for a separate row in the constructed relational view.
1460
1459
1461
1460
@@ -1467,15 +1466,19 @@ where json_table_column is:
1467
1466
the row pattern, extracts a JSON item, and returns it as a
1468
1467
separate SQL value for the specified column. If the required value
1469
1468
is stored in a nested level of the row pattern, it can be extracted
1470
- using the NESTED PATH subclause.
1469
+ using the NESTED PATH subclause. Joining the
1470
+ columns returned by NESTED PATH can add multiple
1471
+ new rows to the constructed view. Such rows are called
1472
+ child rows , as opposed to the parent row
1473
+ that generates them.
1471
1474
1472
1475
1473
1476
1474
1477
The rows produced by JSON_TABLE are laterally
1475
1478
joined to the row that generated them, so you do not have to explicitly join
1476
- the constructed view with the original table. You can specify
1477
- how to handle empty rows returned from the nested levels of
1478
- the row pattern using the PLAN clause.
1479
+ the constructed view with the original table
holding JSON
1480
+ data. Optionally, you can specify how to join the columns returned
1481
+ by NESTED PATH using the PLAN clause.
1479
1482
1480
1483
1481
1484
@@ -1502,18 +1505,16 @@ where json_table_column is:
1502
1505
1503
1506
1504
1507
1505
- COLUMNS( { json_table_column } [, ...] )
1508
+ COLUMNS( { json_table_column } [, ...] )
1506
1509
1507
1510
1508
1511
1509
1512
1510
1513
The COLUMNS clause defining the schema of the
1511
- constructed table. In this clause, you must specify all the columns
1512
- to be filled with SQL/JSON items returned by JSON_TABLE .
1513
- You must provide the name and type for each column. Only scalar
1514
- types are supported.
1514
+ constructed view. In this clause, you must specify all the columns
1515
+ to be filled with SQL/JSON items. Only scalar column types are supported.
1515
1516
The json_table_column
1516
- expression can use one of the following syntax options :
1517
+ expression has the following syntax variants :
1517
1518
1518
1519
1519
1520
@@ -1601,14 +1602,13 @@ where json_table_column is:
1601
1602
so you can go down multiple nested levels by specifying several
1602
1603
NESTED PATH subclauses within each other.
1603
1604
It allows to unnest the hierarchy of JSON objects and arrays
1604
- in a single function invocation rather than chaining several JSON_TABLE
1605
- expressions in an SQL statement.
1605
+ in a single function invocation rather than chaining several
1606
+ JSON_TABLE expressions in an SQL statement.
1606
1607
1607
1608
1608
1609
1609
1610
You can use the PLAN clause to define how
1610
- to handle empty rows when joining the columns returned by
1611
- NESTED PATH clauses.
1611
+ to join the columns returned by NESTED PATH clauses.
1612
1612
1613
1613
1614
1614
@@ -1622,7 +1622,8 @@ where json_table_column is:
1622
1622
1623
1623
Adds an ordinality column that provides sequential row numbering.
1624
1624
You can have only one ordinality column per table. Row numbering
1625
- is 1-based.
1625
+ is 1-based. For child rows that result from the NESTED PATH
1626
+ clauses, the parent row number is repeated.
1626
1627
1627
1628
1628
1629
@@ -1641,28 +1642,31 @@ where json_table_column is:
1641
1642
The optional json_path_name serves as an
1642
1643
identifier of the provided json_path_specification .
1643
1644
The path name must be unique and cannot coincide with column names.
1644
- You must specify the path name when using the PLAN
1645
- clause.
1645
+ When using the PLAN clause, you must specify the names
1646
+ for all the paths, including the row pattern. Each path name can appear in
1647
+ the PLAN clause only once.
1646
1648
1647
1649
1648
1650
1649
1651
1650
1652
1651
1653
1652
- PLAN json_table_plan
1654
+ PLAN ( json_table_plan )
1653
1655
1654
1656
1655
1657
1656
1658
1657
- Defines how to handle empty rows when joining the columns
1658
- returned by NESTED PATH clauses .
1659
+ Defines how to join the data returned by NESTED PATH
1660
+ clauses to the constructed view .
1659
1661
1660
1662
1661
- In relation to the columns returned directly from the row expression
1662
- or by the NESTED PATH clause of a higher level, nested columns
1663
- are considered to be child columns.
1664
- Each NESTED PATH clause can include
1665
- several columns, which are called sibling columns.
1663
+ Each NESTED PATH clause can generate one or more
1664
+ columns, which are considered to be siblings
1665
+ to each other. In relation to the columns returned directly from the row
1666
+ expression or by the NESTED PATH clause of a
1667
+ higher level, these columns are child columns.
1668
+ Sibling columns are always joined first. Once they are processed,
1669
+ the resulting rows are joined to the parent row.
1666
1670
1667
1671
1668
1672
To join columns with parent/child relationship, you can use:
@@ -1675,9 +1679,9 @@ where json_table_column is:
1675
1679
1676
1680
1677
1681
1678
- Use INNER JOIN , so that the output includes
1679
- only those rows that have the corresponding values in both
1680
- columns .
1682
+ Use INNER JOIN , so that the parent row
1683
+ is omitted from the output if it does not have any child rows
1684
+ after joining the data returned by NESTED PATH .
1681
1685
1682
1686
1683
1687
@@ -1689,10 +1693,11 @@ where json_table_column is:
1689
1693
1690
1694
1691
1695
1692
- Use LEFT OUTER JOIN , so that all rows of the
1693
- left-hand column must be included into the output at least once, while the rows of the right-hand
1694
- column are only included if they have a match in the left column. If the corresponding
1695
- value is missing from the right column, the NULL value is inserted into the right column.
1696
+ Use LEFT OUTER JOIN , so that the parent row
1697
+ is always included into the output even if it does not have any child rows
1698
+ after joining the data returned by NESTED PATH , with NULL values
1699
+ inserted into the child columns if the corresponding
1700
+ values are missing.
1696
1701
1697
1702
1698
1703
This is the default option for joining columns with parent/child relationship.
@@ -1713,10 +1718,9 @@ where json_table_column is:
1713
1718
1714
1719
1715
1720
1716
- Use FULL OUTER JOIN , so that all rows of the
1717
- left-hand and the right-hand columns are included into the output, with
1718
- NULL values inserted into either of the columns if the corresponding value
1719
- is missing.
1721
+ Use FULL OUTER JOIN ON FALSE , so that both parent and child
1722
+ rows are included into the output, with NULL values inserted
1723
+ into both child and parrent columns for all missing values.
1720
1724
1721
1725
1722
1726
This is the default option for joining sibling columns.
@@ -1745,11 +1749,17 @@ where json_table_column is:
1745
1749
1746
1750
1747
1751
1748
- PLAN DEFAULT
1752
+ PLAN DEFAULT ( option [, ... ] )
1749
1753
1750
1754
1751
1755
1752
- Redefines the default behavior for all columns at once.
1756
+ Overrides the default joining plans. The INNER and
1757
+ OUTER options define the joining plan for parent/child
1758
+ columns, while UNION and CROSS
1759
+ affect the sibling columns. You can override the default plans for all columns at once.
1760
+ Even though the path names are not incuded into the PLAN DEFAULT
1761
+ clause, they must be provided for all the paths to conform to
1762
+ the SQL/JSON standard.
1753
1763
1754
1764
1755
1765
@@ -1779,8 +1789,36 @@ SELECT jt.* FROM
1779
1789
1 | comedy | The Dinner Game | Francis Veber
1780
1790
2 | horror | Psycho | Alfred Hitchcock
1781
1791
3 | thriller | Vertigo | Hitchcock
1782
- 4 | (null) | Yojimbo | Akira Kurosawa
1792
+ 4 | drama | Yojimbo | Akira Kurosawa
1783
1793
(5 rows)
1794
+
1795
+
1796
+
1797
+
1798
+ Find a director that has done films in two different genres:
1799
+
1800
+ SELECT
1801
+ director1 AS director, title1, kind1, title2, kind2
1802
+ FROM
1803
+ my_films,
1804
+ JSON_TABLE ( js, '$.favorites' AS favs COLUMNS (
1805
+ NESTED PATH '$[*]' AS films1 COLUMNS (
1806
+ kind1 text PATH '$.kind',
1807
+ NESTED PATH '$.films[*]' AS film1 COLUMNS (
1808
+ title1 text PATH '$.title',
1809
+ director1 text PATH '$.director')
1810
+ ),
1811
+ NESTED PATH '$[*]' AS films2 COLUMNS (
1812
+ kind2 text PATH '$.kind',
1813
+ NESTED PATH '$.films[*]' AS film2 COLUMNS (
1814
+ title2 text PATH '$.title',
1815
+ director2 text PATH '$.director'
1816
+ )
1817
+ )
1818
+ )
1819
+ PLAN (favs OUTER ((films1 INNER film1) CROSS (films2 INNER film2)))
1820
+ ) AS jt
1821
+ WHERE kind1 > kind2 AND director1 = director2;
1784
1822
1785
1823
1786
1824
0 commit comments