簡體   English   中英

MySQL 中的 LATERAL 語法 - 是否只是說“左表”首先執行以便下一個可以引用它?

[英]LATERAL syntax in MySQL - Is it just to say that "the left table" is executed first so that the next one can reference it?

派生表不能包含對同一 SELECT 的其他表的引用”是什么意思? 我在 MySQL 文檔中查找了它

SELECT
  salesperson.name,
  max_sale.amount,
  max_sale_customer.customer_name
FROM
  salesperson,
  -- calculate maximum size, cache it in transient derived table max_sale
  LATERAL
  (SELECT MAX(amount) AS amount
    FROM all_sales
    WHERE all_sales.salesperson_id = salesperson.id)
  AS max_sale,
  -- find customer, reusing cached maximum size
  LATERAL
  (SELECT customer_name
    FROM all_sales
    WHERE all_sales.salesperson_id = salesperson.id
    AND all_sales.amount =
        -- the cached maximum size
        max_sale.amount)
  AS max_sale_customer;

派生表不能包含對同一 SELECT 的其他表的引用(為此使用 LATERAL 派生表;請參閱第 13.2.11.9 節,“橫向派生表”)

理解這一點的關鍵在於您已閱讀的手冊:

派生表在查詢期間必須保持不變,不包含對其他 FROM 子句表的列的引用。

也就是說,將派生表視為在查詢的初始時間運行,在連接表中的任何行被讀取之前。 如果派生表子查詢包括對連接表的任何引用,則派生表的結果將取決於從這些表中讀取的數據。 可能與派生表為常量的要求相沖突。

LATERAL改變了這一點。 它確保在查詢開始從聯接表中讀取行之后,稍后評估派生表。

PS:上面 jarlh 的評論並不完全正確。 出於其他原因,建議使用顯式JOIN語法(例如,它支持外連接等),但對於LATERAL而言,它不是必需的。

文檔( 此處)試圖解釋,如果您從select listcorrelated subquery開始,則可以在from clause中引用該表,例如:

SELECT
  salesperson.name,
  -- find maximum sale size for this salesperson
  (SELECT MAX(amount) AS amount
    FROM all_sales
    WHERE all_sales.salesperson_id = salesperson.id)
  AS amount
FROM
  salesperson;

在上面的查詢中,您可以看到 from 表是salesperson ,但在correlated subquery中,您也可以引用salesperson correlation是子查詢通過結果集逐行執行,該子查詢的每次迭代都使用salesperson.id作為 where 子句的輸入。 (順便說一下,這種“逐行”效應通常是為什么correlated subqueries會導致查詢速度變慢。)

但是,在from clause中的傳統derived tables中,不允許使用上述correlation 因此,下面的示例將失敗,因為它嘗試使用不允許的與銷售人員correlation

SELECT
  salesperson.name,
  max_sale.amount,
  max_sale_customer.customer_name
FROM
  salesperson,
  -- calculate maximum size, cache it in transient derived table max_sale
  (SELECT MAX(amount) AS amount
    FROM all_sales
    WHERE all_sales.salesperson_id = salesperson.id)
  AS max_sale
  AS max_sale_customer;

正如文檔所述,這將導致錯誤:

ERROR 1054 (42S22): Unknown column 'salesperson.id' in 'where clause'

但是,通過增加對LATERAL的支持,可以將我們曾經在select clause中使用的correlated subqueries替換為lateral subqueries ,因為這些子查詢確實支持引用from clause中引用的其他表的能力。 此外(不能在select clause中完成)一個lateral subquery可以引用任何先前lateral subquery的結果,這是一個非常有用的功能,文檔中的示例也顯示了這一點:

SELECT
  salesperson.name,
  max_sale.amount,
  max_sale_customer.customer_name
FROM
  salesperson,
  -- calculate maximum size, cache it in transient derived table max_sale
  LATERAL
  (SELECT MAX(amount) AS amount
    FROM all_sales
    WHERE all_sales.salesperson_id = salesperson.id)
  AS max_sale,
  -- find customer, reusing cached maximum size
  LATERAL
  (SELECT customer_name
    FROM all_sales
    WHERE all_sales.salesperson_id = salesperson.id
    AND all_sales.amount =
        -- the cached maximum size
        max_sale.amount) -- refers to prior lateral subquery result
  AS max_sale_customer;

因此,傳統的派生表不能使用相關性,橫向子查詢可以。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM