3

私は本当にこのタスクで立ち往生しています-特定の基準に基づいて「0」の値を持つ行をレポートに入力する必要があります。例を次に示します。

今月とこれまでのすべての月の会社名、取引タイプ、累積金額を含むテーブルBROKERSがあるとします。

COMPANY       TRAN_TYPE          CURR_MNTH         ALL_MNTH  
Broker1       CURRENCY_SELL      $1000.00          $1500000.00 
Broker1       GOLD_SELL          $50000.00         $2500000.00 
Broker1       GOLD_BUY           $80000.00         $8500000.00 
Broker1       STOCKS_SELL        $35000.00         $3500000.00 

テーブルBROKERSにはフィールドTRAN_TYPEがありませんが、すべてのコードが説明されているTRAN_TYPE_CD_EXPLと呼ばれる別のテーブルを参照するフィールドTRAN_TYPE_CDがあります。

TRAN_TYPE_CD  TRAN_TYPE_CD_EXPLD
1             STOCKS_SELL
2             STOCKS_BUY
3             GOLD_SELL
4             GOLD_BUY
5             SILVER_SELL
6             SILVER_BUY
7             COPPER_SELL
8             COPPER_BUY
9             CURRENCY_SELL
10            CURRENCY_BUY

したがって、上記の結果は、これら2つのテーブルを単純に結合したものです。

select  b.COMPANY, tt.TRAN_TYPE, b.CURR_MONTH, b.ALL_MNTH
from    BROKERS b, TRAN_TYPE_CD_EXPL tt
where   b.TRAN_TYPE_CD = tt.TRAN_TYPE_CD;

すべてが非常に単純ですが、ここから問題が始まります。私が取り組んでいるレポートは次のようになります。

COMPANY       MARKET      TRAN_TYPE          CURR_MNTH         ALL_MNTH  
Broker1       FOREX       CURRENCY_SELL      $1000.00          $1500000.00 
Broker1       FOREX       CURRENCY_BUY       $0.00             $5500000.00 
Broker1       CONTRACTS   GOLD_SELL          $50000.00         $2500000.00 
Broker1       CONTRACTS   GOLD_BUY           $80000.00         $8500000.00 
Broker1       STOCKMARKET STOCKS_SELL        $35000.00         $3500000.00 
Broker1       STOCKMARKET STOCKS_BUY         $0.00             $9500000.00 

説明させてください:まず、レポートにはMARKET列が含まれている必要があります。これは、TRAN_TYPE列の値に基づいて入力する必要がありますが、データベースにはMARKETテーブルがないため、毎回、レポートまたは他の場所では、次のようにデコードを使用する必要があります(すべての種類のtran_typeがどこに属するかを誰もが知っていると仮定します):

SELECT DECODE (TRAN_TYPE_CD_EXPL.TRAN_TYPE_CD_EXPLD,
             'CURRENCY_SELL', 'FOREX',
             'CURRENCY_BUY', 'FOREX',
             'STOCKS_SELL', 'STOCKMARKET',
             'STOCKS_BUY', 'STOCKMARKET') AS MARKET,

またはTRAN_TYPE_CD値に基づく:

SELECT DECODE (BROKERS.TRAN_TYPE_CD,
             9, 'FOREX',
             10, 'FOREX',
             1, 'STOCKMARKET',
             2, 'STOCKMARKET') AS MARKET,

2)問題番号2はより複雑です:レポートロジックは次のように述べています-会社が特定のグループに少なくとも1つのトランザクションを持っている場合(たとえば、市場タイプ'FOREX'のCURRENCY_SELL)、レポートには市場タイプの他のtran_typeを入力する必要がありますこの会社が今月中にそれらのトランザクションを持っていなかったとしても、$0のグループ。したがって、この場合、行を入力する必要があります

Broker1       FOREX       CURRENCY_BUY       $0.00             $5500000.00

Broker1       STOCKMARKET STOCKS_BUY         $0.00             $9500000.00

これは、UNIXのplsqlバッチを介して実行されるため、単一のクエリである必要があります。

任意のアイデアや提案は非常に高く評価されています!

ありがとう

PS

そのオラクル11gr2、読み取り専用の役割。

4

4 に答える 4

2

まず、MARKETテーブルを作成できない理由はありますか?それは明らかに最も簡単な解決策になります。ただし、DBアクセス権がなく、クエリにハッキングする必要がある場合は、次のようにすることができます。

WITH m AS (
    select 'CURRENCY_SELL' as tran_type, 'FOREX' as market_name from dual
    UNION ALL
    select 'CURRENCY_BUY' as tran_type, 'FOREX' as market_name from dual
    UNION ALL
    select 'STOCKS_SELL' as tran_type, 'STOCKMARKET' as market_name from dual
    UNION ALL
    select 'STOCKS_BUY' as tran_type, 'STOCKMARKET' as market_name from dual
)
select
    b.company, m.tran_type, m.market_name, 
    nvl(v.curr_month, 0) as curr_month,
    nvl(v.all_mnth, 0) as all_mnth
from
    m
cross join
    (select distinct b.company from brokers) b
left join (
    select b.COMPANY, tt.TRAN_TYPE, b.CURR_MONTH, b.ALL_MNTH
    from    BROKERS b, TRAN_TYPE_CD_EXPL tt
    where   b.TRAN_TYPE_CD = tt.TRAN_TYPE_CD
) v
on v.company = b.company and v.tran_type = m.tran_type;

まず、インラインマーケットビューを使用して企業のクロスジョインを行いました。ブローカーテーブルに一緒に存在しない場合でも、各企業のすべてのレコードの組み合わせを取得します。数値を取得するために左外部結合を実行したので、NULL値が戻ってきた場合(対応するレコードがない場合)は0をプラグインします。

これは正確には正しくないかもしれませんが(たとえば、月をどのように分割するかはわかりません)、正しい方向を示す必要があります。

アップデート

OK、それで私が正しく理解しているなら、あなたは「空の」行を、ブローカーが同じ市場内で少なくとも1つのトランザクションを持っているトランザクションタイプに制限したいと思います。

「BROKERS」は今月のビューであると想定します。したがって、テーブルにレコードがある場合、それは今月に発生します。

したがって、クロス結合を削除して、代わりにこれを行うことができます。

WITH m AS (
    select 9 as tran_type_cd, 'FOREX' as market_name from dual
    UNION ALL
    select 10, 'FOREX' as market_name from dual
    UNION ALL
    select 1, 'STOCKMARKET' from dual
    UNION ALL
    select 2, 'STOCKMARKET' from dual
    UNION ALL 
    SELECT 3, 'CONTRACTS' from dual
    UNION ALL 
    SELECT 4, 'CONTRACTS' from dual
)
select
    bm.company, tt.tran_type, m.market_name, 
    nvl(v.curr_month, 0) as curr_month,
    nvl(v.all_mnth, 0) as all_mnth
from
    (select distinct b.company, m.market_name
     from brokers b
     join m on m.tran_type_cd = b.tran_type_cd) bm
join
    m on m.market_name = bm.market_name
join
    TRAN_TYPE_CD_EXPL tt on tt.tran_type_cd = m.tran_type_cd
left join (
    select b.COMPANY, b.tran_type_cd, b.CURR_MONTH, b.ALL_MNTH
    from    BROKERS b
) v
on v.company = bm.company and v.tran_type_cd = m.tran_type_cd;

ビュー「bm」(素晴らしい頭字語の選択、私は知っています!)は、その月の会社に関連する市場の明確なリストを提供するはずです。次に、マーケットビューに戻って、そのマーケットに関連付けられているすべてのトランザクションタイプを取得しました。以前と同様に、Brokersテーブルに一致するレコードがない場合は、左結合を使用して空の行を0で埋めました。

SQLフィドルは次のとおりです。

http://sqlfiddle.com/#!4/2f16e/13

于 2012-04-16T19:13:38.440 に答える
2

クエリの最初の部分はあなたのものとまったく同じですが、インラインテーブルとしてマーケットがあります。2番目の部分では、マーケットに2回参加して欠落している行を追加し、最初の部分にすでに存在する行を減算して、欠落している行を追加します。

WITH Market AS (
  SELECT 9 TRAN_TYPE_CD, 'FOREX' Market FROM dual
  UNION ALL SELECT 10, 'FOREX' FROM dual
  UNION ALL SELECT 1, 'STOCKMarket'  FROM dual
  UNION ALL SELECT 2, 'STOCKMarket' FROM dual
  UNION ALL SELECT 3, 'CONTRACTS' FROM dual
  UNION ALL SELECT 4, 'CONTRACTS' FROM dual
)
SELECT b.COMPANY, Market.Market, tt.TRAN_TYPE_CD_EXPLD, 
       b.CURR_MONTH, b.ALL_MONTH
  FROM BROKERS b 
 INNER JOIN TRAN_TYPE_CD_EXPL tt
    ON b.TRAN_TYPE_CD = tt.TRAN_TYPE_CD
 INNER JOIN Market
    ON b.TRAN_TYPE_CD = Market.TRAN_TYPE_CD
UNION ALL
(
  SELECT b.COMPANY, Market.Market, tt.TRAN_TYPE_CD_EXPLD, 
         0 CURR_MONTH, 0 ALL_MONTH
    FROM BROKERS b 
   INNER JOIN Market
      ON b.TRAN_TYPE_CD = Market.TRAN_TYPE_CD
   INNER JOIN Market Market2
      ON Market.Market = Market2.Market
     AND Market.TRAN_TYPE_CD <> Market2.TRAN_TYPE_CD
   INNER JOIN TRAN_TYPE_CD_EXPL tt
      ON Market2.TRAN_TYPE_CD = tt.TRAN_TYPE_CD
 MINUS
 SELECT b.COMPANY, Market.Market, tt.TRAN_TYPE_CD_EXPLD, 
        0 CURR_MONTH, 0 ALL_MONTH
   FROM BROKERS b 
  INNER JOIN TRAN_TYPE_CD_EXPL tt
     ON b.TRAN_TYPE_CD = tt.TRAN_TYPE_CD
  INNER JOIN Market
     ON b.TRAN_TYPE_CD = Market.TRAN_TYPE_CD
)

そして、これが結果をテストするためのSqlFiddleです。

于 2012-04-16T20:55:34.947 に答える
1

all_mnthのデータをどこで取得するかわからないため、最初にそれを把握する必要があります。私たちに知らせて、それをゼロ値で結合するのは簡単なはずです。以下は、問題1までのテストクエリです(@Dan Aと同様です。マーケットの「テーブル」を「作成」しました)。

with brokers as
(
select 'Broker1' company, 9 tran_type_cd, 1000  curr_mnth, 1500000 all_mnth from dual union
select 'Broker1' company, 3 tran_type_cd, 50000 curr_mnth, 2500000 all_mnth from dual union
select 'Broker1' company, 4 tran_type_cd, 80000 curr_mnth, 8500000 all_mnth from dual union
select 'Broker1' company, 1 tran_type_cd, 35000 curr_mnth, 3500000 all_mnth from dual 
)
, tran_type_cd_expl as
(
select 1  TRAN_TYPE_CD, 'STOCKS_SELL'  TRAN_TYPE_CD_EXPLD from dual union
select 2  TRAN_TYPE_CD, 'STOCKS_BUY'  TRAN_TYPE_CD_EXPLD from dual union
select 3  TRAN_TYPE_CD, 'GOLD_SELL'  TRAN_TYPE_CD_EXPLD from dual union
select 4  TRAN_TYPE_CD, 'GOLD_BUY'  TRAN_TYPE_CD_EXPLD from dual union
select 5  TRAN_TYPE_CD, 'SILVER_SELL'  TRAN_TYPE_CD_EXPLD from dual union
select 6  TRAN_TYPE_CD, 'SILVER_BUY'  TRAN_TYPE_CD_EXPLD from dual union
select 7  TRAN_TYPE_CD, 'COPPER_SELL'  TRAN_TYPE_CD_EXPLD from dual union
select 8  TRAN_TYPE_CD, 'COPPER_BUY'  TRAN_TYPE_CD_EXPLD from dual union
select 9  TRAN_TYPE_CD, 'CURRENCY_SELL'  TRAN_TYPE_CD_EXPLD from dual union
select 10  TRAN_TYPE_CD, 'CURRENCY_BUY'  TRAN_TYPE_CD_EXPLD from dual 
)
, market as
(
select 'CURRENCY_BUY'  tran_type_cd_expld, 'FOREX'       market from dual union
select 'CURRENCY_SELL' tran_type_cd_expld, 'FOREX'       market from dual union
select 'GOLD_BUY'      tran_type_cd_expld, 'CONTRACTS'   market from dual union
select 'GOLD_SELL'     tran_type_cd_expld, 'CONTRACTS'   market from dual union
select 'STOCKS_BUY'    tran_type_cd_expld, 'STOCKMARKET' market from dual union
select 'STOCKS_SELL'   tran_type_cd_expld, 'STOCKMARKET' market from dual 
)

select company, market, t.tran_type_cd_expld tran_type, curr_mnth, all_mnth
from brokers b, tran_type_cd_expl t, market m
where b.tran_type_cd = t.tran_type_cd
and t.tran_type_cd_expld = m.tran_type_cd_expld
;
于 2012-04-16T19:59:44.270 に答える
0

サブクエリファクタリング(SQL ServerのCTEなど)を使用して行を追加できると思います。回答が得られない場合は、今夜遅くにコードで更新を試みることができます。

于 2012-04-16T19:09:26.107 に答える