天天看點

union(all)學習【七日打卡】

在工作中,檢視到類似于如下的SQL語句:

select sum(count) 
  from (select count(1) count 
          from tb
          left outer join WFWKSEQTAB 
            on tb.JUGSUMID = tb1.SEQNO 
         inner join cdeorg 
            on tb.ibkcde = cdeorg.ibkcde 
         where 1 = 1 
           AND (FNAUTM IS NULL or fnautm = 0) 
           AND (tb.FLWSTS != '3' or tb.FLWSTS IS NULL) 
           and UPPER(tb.customername) like '%' || 'shq_test_20180302' || '%' 
         ESCAPE '/' 
           and tb.biztyp in ('1', '2', '5', '02') 
           and tb.jugsumid in 
               (select jugsumid from casaprlogtab where (1 = 1)) 
        union 
        select count(1) count 
          from tb...複制代碼      
  • Union:對兩個結果集進行并集操作,不包括重複行,同時進行預設規則的排序;
  • Union All:對兩個結果集進行并集操作,包括重複行,不進行排序;

1.Union 指令的目的是将兩個SQL語句的結果合并起來,可以檢視你需要查詢結果

例如:

SELECT Date FROM Store_Information
UNION 
SELECT Date FROM Internet_Sales;複制代碼      

注意

  • union用法中,兩個SELECT 語句的字段類型比對,并且字段的類型要相同.

如上面的例子,在實際的軟體開發過程,會遇到更複雜的情況,具體請看下面的額子

select '1' as type,FL_ID ,FL_CODE,FL_CNAME,_FLDA,FL_PARENTID from FLDA 
WHERE ZT_ID = 2006030002
union
SELECT '2' as Tpye,XM_ID,_XM_CODE,XM_CNAME,FL_ID FROM XMDA 
WHERE exists (SELECT * FROM (SELECT FL_ID FROM FLDA WHERE ZT_ID=200603002 ) a where XMDA.fl_id=fl_id)
order by type,FL_PARENTID , FL_ID;複制代碼      

      這句話的意思是将兩個SQL語句UNION 查詢出來,查詢的條件就是看XMDA表中額FL_ID是否和主表FLDA裡的FL_ID值比對(也就是存在)。

      UNION在進行表連接配接後會篩選掉重複的額記錄,是以表連接配接後會對所産生的結果集進行排序運算,删除重複的記錄再傳回結果。

      2.在查詢中會遇到UNION ALL,他的用法和UNION一樣,隻不過UNION包含distinct的功能,它會把兩張表重複了的記錄去掉,而union all不會, 是以從效率上講,union all 會高一點,但實際中用得到的并不是很多。

      表頭會用到第一個連接配接塊的字段,而UNION all隻是簡單的将兩個結果合并後就傳回,這樣,如果傳回到額兩個結果集中有重複的額資料,那麼傳回到結果集就半含重複的資料了。

      從效率上來說,UNION ALL 要比 UNION快的多,是以,如果可以确認合并的兩個結果集不包含重複的資料的話,那麼就使用UNION ALL如下:

盡量使用UNION ALL,因為UNION需要進行排序,去除重複記錄,效率低。

  • Union可以對字段名不同但資料類型相同的結果集進行合并;
  • 如果字段名不同的結果集進行Union,那麼對此字段的Order by子句将失效;
  • Union,對兩個結果集進行并集操作,不包括重複行,同時進行預設規則的排序;
  • Union All,對兩個結果集進行并集操作,包括重複行,不進行排序;
  • 可以在最後一個結果集中指定Order by子句改變排序方式。

拓展閱讀 using關鍵字學習

另外,在工作中,檢視到類似于如下的SQL語句:

select 
    tb.usrnm, 
    tb.typ, 
    tb.oprorder 
    from tb
    inner join rb1
    using (stfaprid) 
    where tb1.jugsumid = #jugsumid# 
    and tb1.blnorg = #blnorg# 
    and isvld = '1' 
    order by tb.typ asc, tb.oprorder asc 
複制代碼      

      sql/92标準可以使用using關鍵字來簡化連接配接查詢,但是隻是在查詢滿足下面兩個條件時,才能使用using關鍵字進行簡化。

  • 1.查詢必須是等值連接配接。
  • 2.等值連接配接中的列必須具有相同的名稱和資料類型。

      例如:使用using關鍵字,如下:

select emptno,ename,sal,deptno,dname from emp e inner join dept d using(deptno); 
複制代碼      

      如上述語句執行的結果與自然連接配接的結果相同。

      使用using關鍵字簡化連接配接時,需要注意以下幾點:

  • 1.使用emp表和dept表中的deptno列進行連接配接時,在using子句和select子句中,都不能為deptno列指定表名或表别名。
  • 2.如果在連接配接查詢時使用了兩個表中相同的多個列,那麼就可以在using子句中指定多個列名

      形式如下:

select... from table1 inner join table2 using(column1,column2)複制代碼      

      上述的語句相當于下面的語句:

select... from table1 inner join table2
on table1.column1=table2.column2
and table1.column2=table2.column2;複制代碼      

      如果對多個表進行檢索,就必須多次使用using關鍵字進行指定,形式如下:

select... from table1
inner join table2 using(column1)
inner join table3 using(column2);複制代碼      
select... from table1,table2,table3
where table1.column1=table2.column1
and table2.column2=table3.column2;複制代碼      

再議using

在Oracle中的join連接配接中使用using關鍵字,是相對于natural join的。

我們在前面提到,如果是使用natraul join,并且兩張表中如果有多個字段是具有相同的名稱和資料類型的,那麼這些字段都将被oracle自作主張的将他們連接配接起來。

但實際上我們有時候是不需要這樣來連接配接的。我們隻需要将他們的多個具有相同的名稱和資料類型的字段中挑選一兩個。這時候我們就需要用到using 關鍵字了。下面是一個例子。

有一個表是sales,還有一個表是costs,這兩個表中都有兩個字段分别是pro_id和time_id。我們暫且不去考慮下面連接配接的實際意義,僅作文法上的研究。

如果使用natural連接配接,預設情況下,兩個字段将會被自然地連接配接在一起。

Select * from Sales natural join costs;複制代碼      

Select * from Sales join costs on Sales.prod_id = costs.prod_id and sales.time_id = costs.time_id複制代碼      
Select * from Sales ,costs Where Sales.pro_id = cost.prod_id
and sales.time_id = costs.time_id複制代碼      

得到的結果應該是一樣的。如果我們使用自然連接配接,就沒有機會控制連接配接條件,oracle自作主張的将兩個相同資料類型和名稱的字段自然地連接配接在一起了。

Select * from Sales join costs using(prod_id)複制代碼      
  • using中僅能使用一個列名。
  • natural join關鍵字和using關鍵字是互斥的,也就是說不能同時出現。

繼續閱讀