pgsql use of lateral Summary

The lateral pgsql

  • What is LATERAL
  • SQL is the calculation step with LATERAL
  • LATERAL OUTER JOIN restrict the use (or definition of the limits)
  • Few simple examples of LATERAL
  • to sum up

I often use a few chestnuts

First, that scenario:
There is a table commodity goods, there is a evaluation form evaluations. Commodity table and evaluation form are many.
1, in a background, I would like information query goods, while the number of query evaluation of this product.
We can achieve this by

SELECT 
    g.*,
    COUNT(e.*) as num
FROM goods as g
LEFT JOIN evaluation as e on e.goods_id=g.id
WHERE 1=1  GROUP BY g.id

By connecting the left, with the group will be able to achieve
it can also be used to achieve lateral

SELECT 
    g.*,
    ISNUMBER
FROM goods as g
LEFT JOIN LATERAL(
    SELECT COUNT(ev.id) as num FROM  evaluation AS ev 
    WHERE   ev.goods_id=g.id
) AS e ON TRUE
WHERE 1=1 

So it seems not so obvious advantages lateral.
2, we review the query is greater than the number of information items 3

SELECT 
    g.*,
    COUNT(e.*) as num
FROM goods as g
LEFT JOIN evaluation as e on e.goods_id=g.id
HAVING COUNT(e.*)>3   GROUP BY g.id 

This will not succeed, can not find the.
This time you need to use LATERAL

SELECT 
    g.*,
    ISNUMBER
FROM goods as g
LEFT JOIN LATERAL(
    SELECT COUNT(ev.id) as num FROM  evaluation AS ev 
    WHERE   ev.goods_id=g.id
) AS e ON TRUE
WHERE 1=1 AND num>3

3, then we again query information of these goods, hoping to find gold profile comments of product information
LATERAL advantage of this time becomes more apparent

SELECT 
    g.*,
    ISNUMBER
FROM goods as g
LEFT JOIN LATERAL(
     SELECT COUNT(ev.id) as num
     FROM  evaluation AS ev 
     LEFT JOIN  users u  on u.id=ev.user_id
     WHERE   ev.goods_id=g.id AND u.grade=9
) AS e ON TRUE
WHERE 1=1 AND num>0

What is LATERAL

Let's look at the official definition of lateral

LATERAL keyword can be placed before the emergence of the sub-query in FROM. A reference column which allows them to provide the foregoing FROM item (if not the LATERAL, each sub-query is calculated independently, and therefore can not be cross-referenced by other items FROM).
Front table function appears in the FROM keyword can also be put LATERAL, but the keyword is not optional function parameters in any case can contain references to the amount provided in front FROM item column.
LATERAL item can appear in a FROM list item layer, or a JOIN appear in the tree. If the latter occurs in the right part of the JOIN, you can reference any item in the left part of JOIN.
If the entry contains a FROM CROSS-REFERENCE TO LATERAL, the calculation process: for each row FROM provide cross-references to items in a column, or a plurality of providing a plurality of columns FROM A collection of these items, items to be used LATERAL the row or set of rows column value is calculated. They are about to get results and calculated normal line connections. For each row or set of columns from the source table, the process is repeated.

Manual mentioned on:

SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss;    
  
In LATERAL (where you can associate (reference) lateral to the left of the table or clause)  
  
So allow:   
  
LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) 

SQL is the calculation step with LATERAL

1, clause progressive extracts FROM lateral association (reference) or of the ITEM JOIN (also called source table) record (s) in the column (s)

for each row of the FROM item providing the cross-referenced column(s),
or set of rows of multiple FROM items providing the columns,


2, using the above extraction columns (s), the correlation is calculated lateral clause the ITEM
The Item the LATERAL that the using IS EVALUATED external or Row Row set'us The values of Columns.


3, lateral calculations row (s), all from, join ITEM (S) is normally calculated join The resulting row (s) are joined as usual with the rows they were computed from.


4, from 1 to 3 cycle begins, until all the rows of source table depletion.
This is repeated for each row or set of rows from the column source table (s).

LATERAL OUTER JOIN restrict the use (or definition of the limits)

Since the calculation step is the lateral deployment from the source table one by one, it can only be used when the source table as OUTER JOIN whole end, it can not serve as the ITEM within LATERAL WHOLE end.
Therefore, only the right lateral in the left join. Left or right join in. It can not be a WHOLE end.

The column source table(s) must be INNER or LEFT joined to the LATERAL item,   
  
else there would not be a well-defined set of rows from which to compute each set of rows for the LATERAL item.   
  
Thus, although a construct such as X RIGHT JOIN LATERAL Y is syntactically valid,   
  
it is not actually allowed for Y to reference X.  

 Few simple examples of LATERAL

1、
A trivial example of LATERAL is

SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss;

This is not especially useful since it has exactly the same result as the more conventional

SELECT * FROM foo, bar WHERE bar.id = foo.bar_id;

一个LATERAL项可以出现在FROM列表项层
2、
LATERAL is primarily useful when the cross-referenced column is necessary for computing the row(s) to be joined. A common application is providing an argument value for a set-returning function. For example, supposing that vertices(polygon) returns the set of vertices of a polygon, we could identify close-together vertices of polygons stored in a table with:

SELECT p1.id, p2.id, v1, v2
FROM polygons p1, polygons p2,
     LATERAL vertices(p1.poly) v1,
     LATERAL vertices(p2.poly) v2
WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;

This query could also be written

SELECT p1.id, p2.id, v1, v2
FROM polygons p1 CROSS JOIN LATERAL vertices(p1.poly) v1,
     polygons p2 CROSS JOIN LATERAL vertices(p2.poly) v2
WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;

Function calls, application support function to the left of ITEM (S). So you can see the elimination LATERAL, semantics is the same.
(As already mentioned, the LATERAL key word is unnecessary in this example, but we use it for clarity.)

3、
It is often particularly handy to LEFT JOIN to a LATERAL subquery, so that source rows will appear in the result even if the LATERAL subquery produces no rows for them. For example, if get_product_names() returns the names of products made by a manufacturer, but some manufacturers in our table currently produce no products, we could find out which ones those are like this:

SELECT m.name
FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true
WHERE pname IS NULL;

Query results lateral is also possible as a query of the entire statement

to sum up

1, lateral may appear in the list of items FROM layer, it can also appear in several JOIN tree, if it appears in the right part of JOIN, you can reference any item in the left part of JOIN.
2, since the calculation step is the lateral deployment from the source table one by one, it can only be used when the source table as OUTER JOIN whole end, it can not serve as the ITEM within LATERAL WHOLE end.
3, LATERAL keyword can be in a SELECT FROM prefix child. This allows children to refer to the SELECT FROM items listed before the FROM item appears. (No LATERAL words, each SELECT children are independent of each other, it is not possible to cross-reference other items FROM).
4, when a cross-reference LATERAL FROM item contains the calculation process the query as follows: providing a cross-reference for each line in a column, or a plurality of image FROM FROM item provided for a reference to a collection of columns in the row, LATERAL items will use a set of column values of the row or rows to be calculated. the calculated result set, as usual, was added to the joint inquiry in. this process will source table columns repeating the collection line or lines.

reference

[PostgreSQL 9.3 add LATERAL support - LATERAL syntax and usage introduction] https://github.com/digoal/blog/blob/master/201210/20121008_01.md?spm=a2c4e.10696291.0.0.408619a4cXorB6&file=20121008_01.md
[LATERAL ] https://www.postgresql.org/docs/devel/queries-table-expressions.html#QUERIES-LATERAL

Guess you like

Origin www.cnblogs.com/ricklz/p/12122808.html