あなたのコードは、あなたがPRL.start_date
とSL.start_date
を持って示して、あなたはあなたが意味するかを指定するhaving
句に1を修飾する必要があります - あなたはPRL
またはSL
から値をするかどうか。表修飾子を指定しないと、Oracleは参照している表の列を認識しません。エラー・メッセージに示されているように、あいまいです。
しかし、おそらく元のテーブルの列を必要とせず、case文のために作成する列エイリアスを参照しようとしているようです。あなたはそれをすることはできません。それらが定義されているとして、それがin the documentationを言うように列の別名は、order by
句を除き、クエリの同じレベルで使用することはできません。
c_aliasで
列式の別名を指定します。 Oracle Databaseは、このエイリアスを結果セットの列見出しに使用します。 ASキーワードはオプションです。エイリアスは、クエリの期間中、選択リスト項目の名前を変更します。エイリアスは、order_by_clauseでは使用できますが、クエリ内の他の句は使用できません。あなたはcase
文繰り返すのいずれかになります
:
WHERE CASE
WHEN SL.sn IS NOT NULL THEN PRL.start_date
ELSE SL.start_date
END >= To_date('2016-02-28', 'YYYY-MM-DD')
AND (CASE
WHEN SL.sn IS NOT NULL THEN PRL.end_date
ELSE NULL
END <= To_date('2016-04-10', 'YYYY-MM-DD') + 1
OR CASE
WHEN SL.sn IS NOT NULL THEN PRL.end_date
ELSE NULL
END IS NULL)
を(あなたがグループ・バイ節を持っていないので、having
は本当にここに意味をなさないので、私はそれを変更しましたwhere
)、
または副問合せを使用する/ CTE /インライン・ビュー:
SELECT * FROM (
SELECT SL.id,
SL.sn,
SL.title,
CASE
WHEN SL.sn IS NOT NULL THEN PRL.start_date
ELSE SL.start_date
END AS start_date,
CASE
WHEN SL.sn IS NOT NULL THEN PRL.end_date
ELSE NULL
END AS end_date,
SL.father_id,
SL.project,
SL.username,
SL.RUN,
SL.zip_path,
SL.log_file
FROM scheduler_list SL
left join package_running_list PRL
ON SL.sn = PRL.sn
)
WHERE start_date >= To_date('2016-02-28', 'YYYY-MM-DD')
AND (end_date <= To_date('2016-04-10', 'YYYY-MM-DD') + 1
OR end_date IS NULL)
モス元のクエリのtがインラインビューに移動しました。インラインビューは、2つのベーステーブルを参照し、あいまいさがありません。その内側のクエリを独自に実行すると、それが動作することがわかりますが、必要以上のデータが返されます。
SL.sn
への重複参照を削除するように内部クエリを変更しました。そのビューを2回実行すると、同じ名前の2つの列を持つビューと同じORA-00918が発生します。なんらかの理由で2回使用したい場合は、*
を使用する代わりに外側の選択項目に列をリストし、それを繰り返してください。または内側のクエリに複製を保持しますが、別名を使用するようにエイリアスを使用します。私はそれが偶然だったと思う。
外側のwhere
句のstart_date
とend_date
の結果は、内側のクエリのcase
式の結果です。これにより、短くて読みやすく、保守が簡単なケースロジックを繰り返すことがなくなります。ロジックが変更された場合は、2つまたは3つではなく、1つの場所で変更するだけです。
外部クエリでは、内部クエリで使用する基本テーブルまたはそのエイリアスPRLおよびSLを表示できません。その内部問合せからの結果セットしか見ることができず、結果セットの列名にあいまいさはありません。
の質問に関係のない、あなただけ簡潔にするために、ANSI日付リテラルを使用して検討する必要があります:のみ固定リテラルで動作します
WHERE start_date >= DATE '2016-02-28'
AND (end_date IS NULL OR end_date <= DATE '2016-04-10' + 1)
けれども。 +1は実際のコードが日付に変換する文字列を渡されていることを示唆しています。この場合、to_date()
を使用する必要があります。そして最後の比較は<=
ではなく<
であることを意図しているかもしれませんが、伝えるのは難しいでしょう。
テーブルSLとPRLには開始日と終了日があります。あなたはhaving句で使用しているものを指定する必要があるかもしれません。 – SriniV
なぜそれが混乱しますか?あなたのコードはPRL.start_dateとSL.start_dateを持っていることを示しているので、あなたが意味するものを指定するために 'having'節にあるものを修飾する必要があります。 case文のために作成しているエイリアスを参照しようとしている場合、そのことはできません。あなたはまた、having節を持つグループバイを持っていません。 –
OK、どうすればいいですか?@AlexPoole?私はあなたが取るべきものを決めるためにそこに必要がある... – Mojo