演習: 新しいset演算子の使用

この演習では、新しいset演算子EXCEPTEXCEPT ALLおよびINTERSECT ALLの使用方法を示します。

  1. 新しい演習を開始する前に、演習の環境の推奨事項を参照してください。
  2. /home/oracle/labs/M104783GC10/setup_oe_tables.shシェル・スクリプトを実行します。このシェル・スクリプトでは、OE.INVENTORIESOE.ORDERSおよびOE.ORDER_ITEMS表を作成してロードします。
    $ cd /home/oracle/labs/M104783GC10
    $ /home/oracle/labs/M104783GC10/setup_oe_tables.sh
    ...
    Commit complete.
    
    Disconnected from Oracle Database 20c Enterprise Edition Release 20.0.0.0.0 - Production
    Version 20.2.0.0.0
    $
  3. OEとしてPDB20に接続します。
    $ sqlplus oe@PDB20
    SQL*Plus: Release 20.0.0.0.0 - Production on Mon Mar 16 11:32:53 2020
    Version 20.2.0.0.0
    
    Copyright (c) 1982, 2020, Oracle.  All rights reserved.
    
    Enter password: password
    Last Successful login time: Mon Mar 16 2020 11:32:00 +00:00
    
    Connected to:
    Oracle Database 20c Enterprise Edition Release 20.0.0.0.0 - Production
    Version 20.2.0.0.0
    SQL>
  4. INVENTORIES表とORDER_ITEMS表の両方で、インベントリで使用可能な製品の数と顧客がオーダーした製品の数をそれぞれカウントします。
    SQL> SELECT count(distinct product_id) FROM inventories;
    
    COUNT(PRODUCT_ID)
    -----------------
                  208
    
    SQL> SELECT count(distinct product_id) FROM order_items;
    
    COUNT(PRODUCT_ID)
    -----------------
                  185
    			  
    SQL>
  5. インベントリでオーダーされたことのない製品の数はいくつですか。EXCEPT演算子を使用して、最初の問合せで返されたのに2番目では返されなかった一意の行のみを取得します。
    SQL> SELECT count(*) FROM 
           (SELECT product_id FROM inventories
             EXCEPT
            SELECT product_id FROM order_items);
    
      COUNT(*)
    ----------
            84
    
    SQL>
  6. オーダーされた製品のうち、現在インベントリにないのはいくつですか。問合せの順序は結果に関連します。
    SQL> SELECT count(*) FROM 
           (SELECT product_id FROM order_items
              EXCEPT
            SELECT product_id FROM inventories);
    
      COUNT(*)
    ----------
            61
    
    SQL>
  7. ステップ5の問合せで定義された演算子でのALLの使用は、何か意味がありますか。
    SQL> SELECT product_id FROM inventories
              EXCEPT ALL
            SELECT product_id FROM order_items;
    
    PRODUCT_ID
    ----------
          1729
          1729
          1729
          1729
          1729
          1729
          1733
          1733
          1733
          1733
          1733
          1733
          1733
          1733
          1733
    ...
          3502
          3502
          3502
          3502
          3502
          3503
          3503
          3503
          3503
          3503
    
    826 rows selected.
    
    SQL> SELECT count(*) FROM 
           (SELECT product_id FROM inventories
              EXCEPT ALL
            SELECT product_id FROM order_items);
    
      COUNT(*)
    ----------
           826
    
    SQL>

    結果には、すべてのインベントリでオーダーされたことがない製品が含まれる、INVENTORIES表の行がすべて表示されます。これは、何の関連も意味しません。演算子でのALLの使用は適切である必要があります。

  8. オーダーされた製品のうち、まだオーダーできるのはいくつですか。INTERSECT演算子を使用して2つの問合せの結果を結合しているこの文は、両方の問合せによって返される一意の行のみを返します。
    SQL> SELECT count(*) FROM 
           (SELECT product_id FROM inventories
               INTERSECT
            SELECT product_id FROM order_items);
    
      COUNT(*)
    ----------
           124
    
    SQL> SELECT count(*) FROM 
           (SELECT product_id FROM order_items
               INTERSECT
            SELECT product_id FROM inventories);
    
      COUNT(*)
    ----------
           124
    
    SQL>
  9. ステップ8の問合せで定義された演算子でのALLの使用は、何か意味がありますか。
    SQL> SELECT count(*) FROM 
           (SELECT product_id FROM order_items
               INTERSECT ALL
            SELECT product_id FROM inventories);
    
      COUNT(*)
    ----------
           286
    
    SQL> EXIT
    $

    結果には、オーダーされた製品が含まれる、INVENTORIES表の行がすべて表示されます。これは、これらの製品がこれらの倉庫からオーダーされたことを意味しません。この問合せは、何の関連も意味しません。演算子でのALLの使用は適切である必要があります。