2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

S3 Iceberg外部表とOracle DBローカル表を統合し、SELECT AI(NL2SQL)で顧客分析してみた

2
Last updated at Posted at 2026-04-25

この記事は、SnowflakeのIcebergテーブルをOCI Autonomous DatabaseからSELECT AIで自然言語検索してみた の続編です。

はじめに

前編では、Snowflakeで作成したIcebergテーブルをAWS S3に保存し、OCI Autonomous Databaseから外部表として参照しました。さらにSELECT AIを使って、S3上のIcebergデータに対して自然言語で問い合わせるところまで確認しました。

後編では、そこから一歩進めます。

実際の業務では、データレイク上の外部データだけで分析が完結することは少なく、売上データ、マーケティング施策、問い合わせ履歴などは、業務アプリケーションやOracle Database内に存在していることが多いです。

そこで今回は、前編で作成した CUSTOMER_ICEBERGNATION_ICEBERG に加えて、Oracle DB内に以下のローカル表を作成します。

  • ORA_SALES_ORDER
  • ORA_MARKETING_TOUCH
  • ORA_SUPPORT_CASE

そして、これらを統合した V_CUSTOMER_360 ビューを作成し、SELECT AIで自然言語から横断的に問い合わせてみます。

目指すのは、次のような問い合わせです。

  • マーケットセグメントごとの顧客数、総売上、平均売上、サポート問い合わせ件数を表示してください。
  • キャンペーンに反応した顧客と反応していない顧客で、平均売上を比較してください。
  • キャンペーンに反応しており、口座残高が高いが、総売上が低い顧客を営業フォロー候補として10件表示してください。

つまり後編では、単に「Icebergを読めた」だけでなく、外部データとOracle DB内のローカルデータを統合して、SELECT AIで分析するところまでを確認します。

全体像

image.png

■ Part H. Oracle DBのデータと組み合わせて問い合わせる

ここから今ある S3上のIceberg外部表 と、ADB内に作る Oracle DBローカル表 を組み合わせて、分かりやすい「顧客360度分析」を行っていきます。

今あるデータはこうです。

外部データ / Iceberg / S3:
  CUSTOMER_ICEBERG
  NATION_ICEBERG

ここに、Oracle DB側の業務データとして次の3種類を追加します。

Oracle DBローカル表:
  ORA_SALES_ORDER        受注・売上データ
  ORA_MARKETING_TOUCH    キャンペーン接触データ
  ORA_SUPPORT_CASE       問い合わせ・サポートデータ

これで、以下のような統合問い合わせができます。

  • 顧客マスタ・国情報はS3 Icebergから取得
  • 売上・キャンペーン・問い合わせはOracle DB内の表から取得
  • それらを1つのSQLまたはSELECT AIで横断的に問い合わせる

以下では、V_CUSTOMER_360という、外部データとOracle DB内データを統合したビューを作成し、そのビューを対象にSELECT AIを実行していきます。
その結果、ユーザーはSQLを書かずに、顧客、国、売上、キャンペーン、サポートを横断した問い合わせができます。

21. Oracle DBのデータを作成する

まずは顧客300件をOracle DB内にコピーします。
ここでは、Iceberg外部表の CUSTOMER_ICEBERG から300件だけ選び、Oracle DB内のローカル表にします。

CREATE TABLE ORA_LAB_CUSTOMERS AS
SELECT
  t.C_CUSTKEY,
  t.C_NAME,
  t.C_NATIONKEY,
  t.C_MKTSEGMENT,
  t.C_ACCTBAL,
  ROW_NUMBER() OVER (ORDER BY t.C_CUSTKEY) AS RN
FROM (
  SELECT
    C_CUSTKEY,
    C_NAME,
    C_NATIONKEY,
    C_MKTSEGMENT,
    C_ACCTBAL
  FROM CUSTOMER_ICEBERG
  FETCH FIRST 300 ROWS ONLY
) t;

確認します。

SELECT COUNT(*) AS customer_count
FROM ORA_LAB_CUSTOMERS;

結果が 300 ならOKです。

image.png

続いて、Oracle DB内に売上データを作ります。
ORA_SALES_ORDER を作成します。

CREATE TABLE ORA_SALES_ORDER AS
SELECT
  lc.RN * 10 + s.SEQ_NO AS ORDER_ID,
  lc.C_CUSTKEY,
  DATE '2025-01-01' + MOD(lc.RN * 7 + s.SEQ_NO * 11, 120) AS ORDER_DATE,
  CASE MOD(lc.RN + s.SEQ_NO, 3)
    WHEN 0 THEN 'WEB'
    WHEN 1 THEN 'STORE'
    ELSE 'PARTNER'
  END AS CHANNEL,
  CASE MOD(lc.RN + s.SEQ_NO, 5)
    WHEN 0 THEN 'COMPUTE'
    WHEN 1 THEN 'STORAGE'
    WHEN 2 THEN 'DATABASE'
    WHEN 3 THEN 'AI'
    ELSE 'NETWORK'
  END AS PRODUCT_CATEGORY,
  ROUND(
    100
    + MOD(lc.RN * 37 + s.SEQ_NO * 53, 1500)
    + GREATEST(NVL(lc.C_ACCTBAL, 0), 0) * 0.01,
    2
  ) AS ORDER_AMOUNT
FROM ORA_LAB_CUSTOMERS lc
CROSS JOIN (
  SELECT LEVEL AS SEQ_NO
  FROM dual
  CONNECT BY LEVEL <= 3
) s
WHERE MOD(lc.RN + s.SEQ_NO, 4) <> 0;

image.png

確認します。

SELECT COUNT(*) AS order_count
FROM ORA_SALES_ORDER;

中身を確認してみます。
image.png

続いて、キャンペーンデータを作成します。

CREATE TABLE ORA_MARKETING_TOUCH AS
SELECT
  lc.RN AS TOUCH_ID,
  lc.C_CUSTKEY,
  CASE MOD(lc.RN, 4)
    WHEN 0 THEN 'AI導入キャンペーン'
    WHEN 1 THEN 'クラウド移行キャンペーン'
    WHEN 2 THEN 'データ活用キャンペーン'
    ELSE 'セキュリティ強化キャンペーン'
  END AS CAMPAIGN_NAME,
  DATE '2025-01-05' + MOD(lc.RN * 5, 100) AS SENT_DATE,
  CASE
    WHEN MOD(lc.RN, 3) <> 0 THEN 'Y'
    ELSE 'N'
  END AS OPENED_FLAG,
  CASE
    WHEN MOD(lc.RN, 5) = 0 THEN 'Y'
    ELSE 'N'
  END AS CLICKED_FLAG,
  CASE
    WHEN MOD(lc.RN, 5) = 0 THEN 'RESPONDED'
    WHEN MOD(lc.RN, 3) <> 0 THEN 'OPENED_ONLY'
    ELSE 'NO_RESPONSE'
  END AS RESPONSE_STATUS
FROM ORA_LAB_CUSTOMERS lc
WHERE MOD(lc.RN, 2) = 0;

確認します。

SELECT COUNT(*) AS marketing_touch_count
FROM ORA_MARKETING_TOUCH;

サンプルを見ます。

SELECT *
FROM ORA_MARKETING_TOUCH
FETCH FIRST 10 ROWS ONLY;

image.png

続いて、サポート問い合わせデータを作ります。

CREATE TABLE ORA_SUPPORT_CASE AS
SELECT
  lc.RN AS CASE_ID,
  lc.C_CUSTKEY,
  DATE '2025-02-01' + MOD(lc.RN * 3, 90) AS OPENED_DATE,
  CASE MOD(lc.RN, 4)
    WHEN 0 THEN 'PERFORMANCE'
    WHEN 1 THEN 'BILLING'
    WHEN 2 THEN 'USAGE'
    ELSE 'SECURITY'
  END AS ISSUE_TYPE,
  CASE MOD(lc.RN, 3)
    WHEN 0 THEN 'HIGH'
    WHEN 1 THEN 'MEDIUM'
    ELSE 'LOW'
  END AS PRIORITY,
  CASE
    WHEN MOD(lc.RN, 5) = 0 THEN 'OPEN'
    ELSE 'CLOSED'
  END AS STATUS,
  CASE
    WHEN MOD(lc.RN, 5) = 0 THEN CAST(NULL AS NUMBER)
    ELSE MOD(lc.RN, 5) + 1
  END AS SATISFACTION_SCORE
FROM ORA_LAB_CUSTOMERS lc
WHERE MOD(lc.RN, 3) = 0;

確認します。

SELECT COUNT(*) AS support_case_count
FROM ORA_SUPPORT_CASE;

サンプルを見ます。

SELECT *
FROM ORA_SUPPORT_CASE
FETCH FIRST 10 ROWS ONLY;

image.png

22. 検索しやすいようにメタデータとしてコメントを付ける

SELECT AIを使う場合、テーブルや列にコメントがあると意図が伝わりやすくなります。

COMMENT ON TABLE ORA_SALES_ORDER IS
'Oracle DB内のサンプル受注データ。CUSTOMER_ICEBERGのC_CUSTKEYと結合する。';

COMMENT ON COLUMN ORA_SALES_ORDER.C_CUSTKEY IS
'顧客キー。CUSTOMER_ICEBERG.C_CUSTKEYと結合する。';

COMMENT ON COLUMN ORA_SALES_ORDER.ORDER_AMOUNT IS
'受注金額。売上集計に使用する。';

COMMENT ON TABLE ORA_MARKETING_TOUCH IS
'Oracle DB内のサンプルキャンペーン接触データ。顧客ごとの開封、クリック、反応状況を持つ。';

COMMENT ON COLUMN ORA_MARKETING_TOUCH.C_CUSTKEY IS
'顧客キー。CUSTOMER_ICEBERG.C_CUSTKEYと結合する。';

COMMENT ON COLUMN ORA_MARKETING_TOUCH.RESPONSE_STATUS IS
'キャンペーン反応状況。RESPONDED、OPENED_ONLY、NO_RESPONSEのいずれか。';

COMMENT ON TABLE ORA_SUPPORT_CASE IS
'Oracle DB内のサンプルサポート問い合わせデータ。顧客ごとの問い合わせ種別、優先度、満足度を持つ。';

COMMENT ON COLUMN ORA_SUPPORT_CASE.C_CUSTKEY IS
'顧客キー。CUSTOMER_ICEBERG.C_CUSTKEYと結合する。';

COMMENT ON COLUMN ORA_SUPPORT_CASE.SATISFACTION_SCORE IS
'サポート満足度。1から5の数値。未解決の場合はNULL。';

23. インデックスを作る

サンプルデータは小さいので必須ではありませんが、結合列にインデックスを作っておくと分かりやすいです。

CREATE INDEX IDX_ORA_LAB_CUSTOMERS_KEY
ON ORA_LAB_CUSTOMERS(C_CUSTKEY);

CREATE INDEX IDX_ORA_SALES_ORDER_CUST
ON ORA_SALES_ORDER(C_CUSTKEY);

CREATE INDEX IDX_ORA_MARKETING_TOUCH_CUST
ON ORA_MARKETING_TOUCH(C_CUSTKEY);

CREATE INDEX IDX_ORA_SUPPORT_CASE_CUST
ON ORA_SUPPORT_CASE(C_CUSTKEY);

24. 顧客360度ビューを作る

複数の表を毎回直接JOINすると、注文と問い合わせの組み合わせで件数が増えてしまい、売上が二重計上されることがあります。

そのため、先に顧客単位で集計したビューを作ります。
これが今回の統合問い合わせの中心になります。

こちらをクリックしてSQL文を表示:point_down:
CREATE OR REPLACE VIEW V_CUSTOMER_360 AS
WITH sales AS (
  SELECT
    C_CUSTKEY,
    COUNT(*) AS ORDER_COUNT,
    ROUND(SUM(ORDER_AMOUNT), 2) AS TOTAL_SALES,
    ROUND(AVG(ORDER_AMOUNT), 2) AS AVG_ORDER_AMOUNT,
    MAX(ORDER_DATE) AS LAST_ORDER_DATE
  FROM ORA_SALES_ORDER
  GROUP BY C_CUSTKEY
),
marketing AS (
  SELECT
    C_CUSTKEY,
    COUNT(*) AS CAMPAIGN_TOUCH_COUNT,
    SUM(CASE WHEN OPENED_FLAG = 'Y' THEN 1 ELSE 0 END) AS OPENED_COUNT,
    SUM(CASE WHEN CLICKED_FLAG = 'Y' THEN 1 ELSE 0 END) AS CLICKED_COUNT,
    SUM(CASE WHEN RESPONSE_STATUS = 'RESPONDED' THEN 1 ELSE 0 END) AS RESPONDED_COUNT
  FROM ORA_MARKETING_TOUCH
  GROUP BY C_CUSTKEY
),
support AS (
  SELECT
    C_CUSTKEY,
    COUNT(*) AS SUPPORT_CASE_COUNT,
    SUM(CASE WHEN STATUS = 'OPEN' THEN 1 ELSE 0 END) AS OPEN_CASE_COUNT,
    ROUND(AVG(SATISFACTION_SCORE), 2) AS AVG_SATISFACTION_SCORE
  FROM ORA_SUPPORT_CASE
  GROUP BY C_CUSTKEY
),
nation_dedup AS (
  SELECT
    N_NATIONKEY,
    MAX(N_NAME) AS N_NAME
  FROM NATION_ICEBERG
  GROUP BY N_NATIONKEY
)
SELECT
  lc.C_CUSTKEY,
  lc.C_NAME AS CUSTOMER_NAME,
  n.N_NAME AS NATION,
  lc.C_MKTSEGMENT AS MARKET_SEGMENT,
  lc.C_ACCTBAL AS ACCOUNT_BALANCE,

  NVL(s.ORDER_COUNT, 0) AS ORDER_COUNT,
  NVL(s.TOTAL_SALES, 0) AS TOTAL_SALES,
  NVL(s.AVG_ORDER_AMOUNT, 0) AS AVG_ORDER_AMOUNT,
  s.LAST_ORDER_DATE,

  NVL(m.CAMPAIGN_TOUCH_COUNT, 0) AS CAMPAIGN_TOUCH_COUNT,
  NVL(m.OPENED_COUNT, 0) AS OPENED_COUNT,
  NVL(m.CLICKED_COUNT, 0) AS CLICKED_COUNT,
  NVL(m.RESPONDED_COUNT, 0) AS RESPONDED_COUNT,

  NVL(sp.SUPPORT_CASE_COUNT, 0) AS SUPPORT_CASE_COUNT,
  NVL(sp.OPEN_CASE_COUNT, 0) AS OPEN_CASE_COUNT,
  sp.AVG_SATISFACTION_SCORE
FROM ORA_LAB_CUSTOMERS lc
LEFT JOIN nation_dedup n
  ON lc.C_NATIONKEY = n.N_NATIONKEY
LEFT JOIN sales s
  ON lc.C_CUSTKEY = s.C_CUSTKEY
LEFT JOIN marketing m
  ON lc.C_CUSTKEY = m.C_CUSTKEY
LEFT JOIN support sp
  ON lc.C_CUSTKEY = sp.C_CUSTKEY;

さらにコメントも付けます。

COMMENT ON TABLE V_CUSTOMER_360 IS
'S3 Iceberg上の顧客・国データと、Oracle DB内の売上・キャンペーン・サポートデータを統合した顧客360度ビュー。';

COMMENT ON COLUMN V_CUSTOMER_360.CUSTOMER_NAME IS
'顧客名。CUSTOMER_ICEBERG由来。';

COMMENT ON COLUMN V_CUSTOMER_360.NATION IS
'国名。NATION_ICEBERG由来。';

COMMENT ON COLUMN V_CUSTOMER_360.MARKET_SEGMENT IS
'顧客のマーケットセグメント。CUSTOMER_ICEBERG由来。';

COMMENT ON COLUMN V_CUSTOMER_360.TOTAL_SALES IS
'Oracle DB内の受注データから計算した顧客別総売上。';

COMMENT ON COLUMN V_CUSTOMER_360.RESPONDED_COUNT IS
'キャンペーンに反応した回数。';

COMMENT ON COLUMN V_CUSTOMER_360.SUPPORT_CASE_COUNT IS
'サポート問い合わせ件数。';

COMMENT ON COLUMN V_CUSTOMER_360.AVG_SATISFACTION_SCORE IS
'サポート満足度の平均。';

25. 統合ビューを確認する

SELECT COUNT(*) AS customer_360_count
FROM V_CUSTOMER_360;

300件になればOKです。

中身を確認します。
image.png

この後、SELECT AIで自然言語問い合わせをする前に、統合ビュー V_CUSTOMER_360 が正しく分析に使える状態かを確認しておきます。

  • 売上上位顧客トップ10

このSQLで、【S3 Iceberg上の外部データ】+【Oracle DB内のローカル業務データ】が、V_CUSTOMER_360 を通じて一緒に問い合わせできていることを確認しています。

SELECT
  CUSTOMER_NAME,
  NATION,
  MARKET_SEGMENT,
  TOTAL_SALES,
  ORDER_COUNT,
  RESPONDED_COUNT,
  SUPPORT_CASE_COUNT
FROM V_CUSTOMER_360
ORDER BY TOTAL_SALES DESC
FETCH FIRST 10 ROWS ONLY;

CUSTOMER_NAME → Iceberg由来の顧客情報
NATION → Iceberg由来の国情報
MARKET_SEGMENT → Iceberg由来の顧客セグメント
TOTAL_SALES / ORDER_COUNT→ Oracle DB内に追加した売上データ
RESPONDED_COUNT → Oracle DB内に追加したマーケティング反応データ
SUPPORT_CASE_COUN → Oracle DB内に追加したサポート問い合わせデータ

マーケットセグメント別の売上・問い合わせ
SELECT
  MARKET_SEGMENT,
  COUNT(*) AS CUSTOMER_COUNT,
  SUM(ORDER_COUNT) AS ORDER_COUNT,
  ROUND(SUM(TOTAL_SALES), 2) AS TOTAL_SALES,
  ROUND(AVG(TOTAL_SALES), 2) AS AVG_SALES_PER_CUSTOMER,
  SUM(SUPPORT_CASE_COUNT) AS SUPPORT_CASE_COUNT
FROM V_CUSTOMER_360
GROUP BY MARKET_SEGMENT
ORDER BY TOTAL_SALES DESC;

image.png

国別・マーケットセグメント別の売上
SELECT
  NATION,
  MARKET_SEGMENT,
  COUNT(*) AS CUSTOMER_COUNT,
  SUM(ORDER_COUNT) AS ORDER_COUNT,
  ROUND(SUM(TOTAL_SALES), 2) AS TOTAL_SALES,
  ROUND(AVG(ACCOUNT_BALANCE), 2) AS AVG_ACCOUNT_BALANCE
FROM V_CUSTOMER_360
GROUP BY
  NATION,
  MARKET_SEGMENT
HAVING SUM(TOTAL_SALES) > 0
ORDER BY TOTAL_SALES DESC
FETCH FIRST 20 ROWS ONLY;
キャンペーン反応あり/なしで売上を比較
SELECT
  CASE
    WHEN RESPONDED_COUNT > 0 THEN 'RESPONDED'
    ELSE 'NOT_RESPONDED'
  END AS CAMPAIGN_GROUP,
  COUNT(*) AS CUSTOMER_COUNT,
  ROUND(SUM(TOTAL_SALES), 2) AS TOTAL_SALES,
  ROUND(AVG(TOTAL_SALES), 2) AS AVG_SALES_PER_CUSTOMER,
  ROUND(AVG(ORDER_COUNT), 2) AS AVG_ORDER_COUNT
FROM V_CUSTOMER_360
GROUP BY
  CASE
    WHEN RESPONDED_COUNT > 0 THEN 'RESPONDED'
    ELSE 'NOT_RESPONDED'
  END
ORDER BY TOTAL_SALES DESC;

image.png

サポート問い合わせあり/なしで売上を比較
SELECT
  CASE
    WHEN SUPPORT_CASE_COUNT > 0 THEN 'HAS_SUPPORT_CASE'
    ELSE 'NO_SUPPORT_CASE'
  END AS SUPPORT_GROUP,
  COUNT(*) AS CUSTOMER_COUNT,
  ROUND(AVG(TOTAL_SALES), 2) AS AVG_SALES_PER_CUSTOMER,
  ROUND(AVG(ACCOUNT_BALANCE), 2) AS AVG_ACCOUNT_BALANCE,
  ROUND(AVG(AVG_SATISFACTION_SCORE), 2) AS AVG_SATISFACTION_SCORE
FROM V_CUSTOMER_360
GROUP BY
  CASE
    WHEN SUPPORT_CASE_COUNT > 0 THEN 'HAS_SUPPORT_CASE'
    ELSE 'NO_SUPPORT_CASE'
  END;

image.png

営業フォロー候補の顧客
「キャンペーンに反応していて、口座残高も高いが、売上がまだ低め」の顧客を探します。
SELECT
  CUSTOMER_NAME,
  NATION,
  MARKET_SEGMENT,
  ACCOUNT_BALANCE,
  TOTAL_SALES,
  RESPONDED_COUNT,
  SUPPORT_CASE_COUNT
FROM V_CUSTOMER_360
WHERE RESPONDED_COUNT > 0
  AND ACCOUNT_BALANCE > (
    SELECT AVG(ACCOUNT_BALANCE)
    FROM V_CUSTOMER_360
  )
  AND TOTAL_SALES < (
    SELECT AVG(TOTAL_SALES)
    FROM V_CUSTOMER_360
  )
ORDER BY ACCOUNT_BALANCE DESC
FETCH FIRST 10 ROWS ONLY;

image.png

キャンペーンには反応している
資金余力もありそう
でもまだ購入額は平均より低い
→ 営業フォロー候補

26. SELECT AI用のプロファイルを追加する

新しくAIプロファイルを作成します。

名前はGENAI_CUSTOMER360にします。

BEGIN
  BEGIN
    DBMS_CLOUD_AI.DROP_PROFILE('GENAI_CUSTOMER360');
  EXCEPTION
    WHEN OTHERS THEN NULL;
  END;

  DBMS_CLOUD_AI.CREATE_PROFILE(
    profile_name => 'GENAI_CUSTOMER360',
    attributes   => '{
      "provider"       : "oci",
      "credential_name": "OCI_GENAI",
      "model"          : "xai.grok-4",
      "region"         : "us-chicago-1",
      "object_list"    : [
        {"owner": "ADMIN", "name": "V_CUSTOMER_360"}
      ],
      "comments": true
    }'
  );
END;
/

27. SELECT AIでSQLだけ生成して確認する

最初は showsql にして生成されるSQLを確認します。

セグメント別の売上分析

V_CUSTOMER_360を使って、マーケットセグメントごとの顧客数、総売上、平均売上、サポート問い合わせ件数を表示してください。総売上が多い順に並べてください。

SELECT DBMS_CLOUD_AI.GENERATE(
  prompt       => 'V_CUSTOMER_360を使って、マーケットセグメントごとの顧客数、総売上、平均売上、サポート問い合わせ件数を表示してください。総売上が多い順に並べてください。',
  profile_name => 'GENAI_CUSTOMER360',
  action       => 'showsql'
) AS generated_sql
FROM dual;

image.png

explainsqlにすると、自然言語で生成されたSQLを説明されます。

image.png

生成されたSQLが良さそうな場合は、 runsql にして実行します。

image.png

image.png

国別・セグメント別の分析

V_CUSTOMER_360を使って、国別、マーケットセグメント別に、顧客数、注文数、総売上、平均口座残高を集計してください。総売上が多い順に上位20件を表示してください

SELECT DBMS_CLOUD_AI.GENERATE(
  prompt       => 'V_CUSTOMER_360を使って、国別、マーケットセグメント別に、顧客数、注文数、総売上、平均口座残高を集計してください。総売上が多い順に上位20件を表示してください。',
  profile_name => 'GENAI_CUSTOMER360',
  action       => 'showsql'
) AS generated_sql
FROM dual;

image.png

キャンペーン反応あり/なしの比較

V_CUSTOMER_360を使って、キャンペーンに反応した顧客と反応していない顧客で、顧客数、平均売上、総売上、平均注文数を比較してください。

SELECT DBMS_CLOUD_AI.GENERATE(
  prompt       => 'V_CUSTOMER_360を使って、キャンペーンに反応した顧客と反応していない顧客で、顧客数、平均売上、総売上、平均注文数を比較してください。',
  profile_name => 'GENAI_CUSTOMER360',
  action       => 'showsql'
) AS generated_sql
FROM dual;

image.png

キャンペーンに反応した顧客は、反応していない顧客より人数は少ないものの、平均売上・平均注文数・総売上が高いことがわかります。

サポート問い合わせあり/なしの比較

V_CUSTOMER_360を使って、サポート問い合わせがある顧客とない顧客で、顧客数、平均売上、平均口座残高、平均サポート満足度を比較してください。

SELECT DBMS_CLOUD_AI.GENERATE(
  prompt       => 'V_CUSTOMER_360を使って、サポート問い合わせがある顧客とない顧客で、顧客数、平均売上、平均口座残高、平均サポート満足度を比較してください。',
  profile_name => 'GENAI_CUSTOMER360',
  action       => 'showsql'
) AS generated_sql
FROM dual;

image.png

サポート問い合わせがある顧客は、問い合わせがない顧客と比較し、平均売上・平均口座残高・サポート満足度が高いことがわかります。

営業フォロー候補を探す

V_CUSTOMER_360を使って、キャンペーンに反応しており、口座残高が高いが、総売上が低い顧客を営業フォロー候補として10件表示してください。顧客名、国、マーケットセグメント、口座残高、総売上、キャンペーン反応回数を表示してください。

SELECT DBMS_CLOUD_AI.GENERATE(
  prompt       => 'V_CUSTOMER_360を使って、キャンペーンに反応しており、口座残高が高いが、総売上が低い顧客を営業フォロー候補として10件表示してください。顧客名、国、マーケットセグメント、口座残高、総売上、キャンペーン反応回数を表示してください。',
  profile_name => 'GENAI_CUSTOMER360',
  action       => 'showsql'
) AS generated_sql
FROM dual;

外部データレイク(S3)とOracle DB内の業務データを統合し、SELECT AIで分析することができました!

まとめ

後編では、前編で作成したS3上のIceberg外部表に加えて、Oracle DB内に売上、マーケティング、サポート問い合わせのローカル表を作成しました。

そして、それらを統合した V_CUSTOMER_360 ビューを作成し、通常SQLとSELECT AIの両方から問い合わせてみました。

今回の構成により、以下のようなことが確認できました。

  • S3上のIcebergデータをADBから外部表として参照できる
  • Oracle DB内のローカル表と外部表をSQLで統合できる
  • 統合ビューを作ることで、SELECT AIから自然言語で問い合わせやすくなる
  • 顧客、国、売上、キャンペーン、サポート問い合わせを横断した分析ができる

前編では「Snowflakeが作成したIcebergデータをADBからSELECT AIで問い合わせる」ことを確認しました。

後編ではそこからさらに進めて、「外部データレイク上のデータ」と「Oracle DB内の業務データ」を統合し、SELECT AIで分析する形に拡張しました。

すべてのデータを1か所にコピーするのではなく、外部データは外部表として参照し、Oracle DB内のデータと必要に応じて統合することで、柔軟な分析基盤を作ることができます。

SELECT AIを組み合わせることで、SQLに詳しくないユーザーでも、自然言語で分析観点を指定できるようになります。

今回の検証を通じて、Apache Iceberg、Autonomous Database、SELECT AIを組み合わせることで、データレイクとデータベースをまたいだ分析を比較的シンプルに実現できることが確認できました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?