2016-11-11 21 views
1

サブSELECTを使用して関連するテーブルから最後の行を取得しようとしていますが、サブセレクトが外部クエリに含まれるテーブルの1つを知らないようですkd.KPI_DEF_IDの無効な識別子です。これを数字に置き換えると、クエリが有効になります。Oracle:サブセレクト内の無効な識別子

SELECT bp.bp_id, 
    kd.kpi_def_id, 
    kd.kpi_name, 
    ks.kpi_status_now, 
    kd.threshold_min_val, 
    kd.threshold_max_val, 
    kd.threshold_min_alert, 
    kd.threshold_max_alert, 
    e.event_id, 
    e.event_name, 
    (SELECT * 
     FROM (SELECT l.log_desc 
      FROM rator_monitoring.alert_logs l 
      WHERE l.kpi_def_id = kd.kpi_def_id 
      ORDER BY TIMESTAMP DESC) 
     WHERE rownum = 1) log_desc 
FROM business_process bp 
JOIN kpi_definition kd 
ON  (kd.bp_id = bp.bp_id) 
JOIN rator_monitoring.kpi_status ks 
ON  (ks.kpi_def_id = kd.kpi_def_id) 
JOIN event e 
ON  (e.event_id = kd.event_id) 
WHERE kd.kpi_active_current = 'Y'; 

これを解決するにはどうすればよいですか?

+1

最も外側のクエリのテーブルを参照するサブクエリがあります。悲しいかな、オラクルでは、1つ以上のレベルの表を参照することはできません。 (どちらがうんざり!)どのOracleのバージョンを使用していますか? Oracle 11以降では、これを修正する最良の方法はWITH句を使用することです。 – mathguy

+4

悪いニュースは1レベル以上を参照できないことです。 (これは設計によるものです)KDへの参照はあまりにも遠すぎます。クエリを再構成する必要があります。いずれかの方法でCTEまたは選択をmovにしてください... – xQbert

答えて

3

相関結合が最上位レベルで行われるように、log_descスカラーサブクエリを変換する必要があります。たとえば、次のようなものがあります。

SELECT ... 
     (SELECT max(l.log_desc) keep (dense_rank first order by l.timestamp desc) 
     FROM rator_monitoring.alert_logs l 
     WHERE l.kpi_def_id = kd.kpi_def_id) log_desc 
FROM ... 

N.B.テストされていない。

+0

動作しますが、少し遅いです。私は病気が敗北を認め、それを2つのクエリに分割していると思います。 – Adder

1

UNTESTED:インラインビューを使用して結合として再構成されます。パフォーマンスについてはわかりません。

SELECT bp.bp_id, 
    kd.kpi_def_id, 
    kd.kpi_name, 
    ks.kpi_status_now, 
    kd.threshold_min_val, 
    kd.threshold_max_val, 
    kd.threshold_min_alert, 
    kd.threshold_max_alert, 
    e.event_id, 
    e.event_name, 
    l.log_desc 
FROM business_process bp 
JOIN kpi_definition kd 
    ON kd.bp_id = bp.bp_id 
JOIN rator_monitoring.kpi_status ks 
    ON ks.kpi_def_id = kd.kpi_def_id 
JOIN event e 
    ON e.event_id = kd.event_id 
LEFT JOIN (SELECT log_Desc 
     FROM rator_monitoring.alert_logs 
     INNER JOIN (SELECT max(timestamp) mts, kpi_def_ID 
        FROM rator_monitoring.alert_logs 
        GROUP BY kpi_def_ID) Z 
      ON Z.mts = l.timestamp 
     AND Z.kpi_def_ID = l.kpi_def_ID) l 
    ON l.kpi_def_id = kd.kpi_def_id 
WHERE kd.kpi_active_current = 'Y'; 
+0

alert_logsテーブルからkpi_definitionテーブルへの左外部結合でなければなりませんか? – Boneist

+2

ああ、そうです。各レコードのログDescがない可能性があります。 (kp_def_id、timestamp) 'tupleが一意であることが保証されていない場合、' l'は 'kpi_def_id'と同じ値を持つ複数の行を持つ可能性があることに注意してください。 – xQbert

+0

'lp'が' kp_def_id'につき最大で1行を返すようにするには、 'GROUP BY kp_def_id'と' log_desc'を集約する必要があります... 'MIN(log_desc)'または 'MAX(log_desc)' – spencer7593

関連する問題