馬哈魚數據血緣分析器中的子查詢語句分析

在實際生產環境中,無論你的業務複雜與否,子查詢都是繞不開的話題,本文帶你了解一下馬哈魚數據血緣分析器是如果處理各種子查詢的。通過本文你能了解到不同場景的子查詢在馬哈魚中的展示狀態。

嵌套子查詢可以說是SQL語句中比較複雜的一部分,它可以提高查詢效率,簡化SQL語句的實現邏輯。子查詢指的是一個查詢語塊可以嵌套在另外一個查詢語句塊的Form子句、where子句或者having子句中,根據位置不同可分為為子查詢或內查詢,後者為父查詢或外查詢。

下面我們逐步分析各種使用場景中子查詢對應馬哈魚中的顯示狀態:

一、子查詢分類場景分析

1、在From中聲明子查詢

最常見的子查詢使用場景之一是它作為派生表與其他表或視圖進行關聯分析,這一類子查詢主要有兩種類型,一種是子查詢作為派生表與其他表進行關聯;另一種是子查詢形成的派生表作為外層查詢的唯一表。後者是前者的一種特殊情況,這兩種情況下,子查詢所產生的的中間結果集均會被馬哈魚顯示並作為外層結果集的部分或全部數據源,如下:

--形式一:子查詢派生表與其他表進行關聯
SELECT e.employee_id,e.last_name,e.salary,dept_avg_sal.avg_sal
FROM employees e,(
        SELECT department_id,AVG(salary) avg_sal
        FROM employees
        GROUP BY department_id
        )  dept_avg_sal
WHERE e.department_id = dept_avg_sal.department_id
AND e.salary > dept_avg_sal.avg_sal

image-20210917223501706

形式二:子查詢作為派生表
select * from (
  select dt.d_year
    ,item.i_brand_id brand_id
    ,item.i_brand brand
    ,sum(ss.ss_sales_price) sum_agg
 from date_dim dt
   ,store_sales ss
   ,item
 where dt.d_date_sk = store_sales.ss_sold_date_sk
  and store_sales.ss_item_sk = item.i_item_sk
  and item.i_manufact_id = 816
  and dt.d_moy=11
 group by dt.d_year
   ,item.i_brand
   ,item.i_brand_id
 order by dt.d_year
     ,sum_agg desc
     ,brand_id
        ) where rownum <= 100;

image-20210917224328673

2、單值子查詢

單值子查詢作為子查詢中較為常見的一種使用方式,它可以是相關子查詢也可以是不相關子查詢,它產生的結果集因為僅作用於限制外層查詢返回數據的多少,本身並不影響外層查詢返回的列數,所以,它的中間結果集會被單獨列出,如下圖:

SELECT employee_id,last_name,salary
FROM employees e1
WHERE salary > (
        SELECT AVG(salary)
        FROM employees e2
        WHERE e2.department_id = e1.department_id  );

image-20210917223809982

3、返回結果集中的子查詢

返回結果集中的子查詢必須是返回單列,一般是相關子查詢,它返回的值作為外層查詢的一個列,直接影響到最終查詢結果集,所以它的中間結果集的地位會會像其他表或視圖一樣,作為最終結果集的源數據提供者,如下圖:

--子查詢作為返回值
select dt.d_year
    ,item.i_brand_id brand_id
    ,item.i_brand brand
    ,sum(ss.ss_sales_price) sum_agg
  ,(select score from  store_sales where storeid=1) score
 from date_dim dt
   ,store_sales ss
   ,item
 where dt.d_date_sk = store_sales.ss_sold_date_sk
  and store_sales.ss_item_sk = item.i_item_sk
  and item.i_manufact_id = 816
  and dt.d_moy=11
 group by dt.d_year
   ,item.i_brand
   ,item.i_brand_id
 order by dt.d_year
     ,sum_agg desc
     ,brand_id

image-20210917225457503

4、嵌套子查詢–IN表達式

嵌套子查詢(in)它可以是相關子查詢也可以是不相關子查詢,它產生的結果集因為僅作用於篩選外層查詢返回數據的多少,本身並不影響外層查詢返回的列數,所以,它的中間結果集會被單獨列出,如下圖

--子查詢在in表達式內
SELECT employee_id,last_name,job_id,department_id
FROM employees
WHERE employee_id IN (
            SELECT DISTINCT manager_id
            FROM employees);

image-20210917230154021

5、嵌套子查詢–[not]exists表達式

嵌套子查詢([not]exists)它可以是相關子查詢也可以是不相關子查詢,它產生的結果集因為僅作用於篩選外層查詢返回數據的多少,本身並不影響外層查詢返回的列數,所以,它的中間結果集會被單獨列出,如下圖

--場景一:子查詢中返回表中列
SELECT employee_id,last_name,job_id,department_id
FROM employees e1
WHERE EXISTS (
        SELECT employee_id
        FROM employees 
        WHERE e1.employee_id = manager_id
        );
       

image-20210917230543519

--場景二:子查詢中返回常量
SELECT employee_id,last_name,job_id,department_id
FROM employees e1
WHERE EXISTS (
        SELECT 1
        FROM employees 
        WHERE e1.employee_id = manager_id
        );

image-20210917230807539

6、在having子句中使用子查詢

having子句中的子查詢也是用於篩選分組後的數據集合,它本質還是用於篩選數據本身,並不會影響外層結果集的結構,所以它的中間結果集會被單獨列出,如下圖:

--在having子句中使用子查詢
SELECT d.deptno,d.dname,AVG(e.sal) avgsal
FROM emp e,dept d
WHERE e.deptno=d.deptno
GROUP BY d.deptno,d.dname
HAVING AVG(e.sal)=(SELECT MAX(AVG(sal))
     FROM emp GROUP BY deptno);

image-20210918000210984

二、總結分析

通過分析子查詢的各種使用場景,我們不難發現,子查詢的位置決定了它所形成的中間結果集在馬哈魚分析結果上的位置,根據子查詢所在的位置,我們可以簡單總結如下:

  • where子句之前的子查詢,它的中間結果集會參與它外層查詢的結果集的形成,中間結果集在馬哈魚分析介面上和表或視圖地位一致;
  • where子句之後的子查詢,它的結果集僅參與外層查詢返回數據的篩選限制,本身不會對外層查詢結果集的結構產生影響,馬哈魚將它的中間結果集和外層結果集並列展示。

三、參照

馬哈魚數據血緣分析器: //sqlflow.gudusoft.com

馬哈魚數據血緣分析器中文網站: //www.sqlflow.cn