質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

3回答

3668閲覧

【PostgreSQL】複数カラムからの最古日付取得について

d_11

総合スコア6

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2018/03/04 14:19

編集2018/03/04 14:24

あるテーブル(例:TESTテーブル)に5つの日付が格納されるカラムが存在します。

そのカラムは以下の条件が現状確認されています。
・データ型:VARCHAR
・基本"YYYY/MM/DD"形式の日付が挿入されるが、NULLや空白が稀に挿入される。
・過去/現在/未来どの日付も挿入される可能性がある。

その5つのカラムの中で最古の日付を取得する必要があるのですが
TO_DATEで変換する場合、NULLであったカラムの日付変換時に不正な文字列となるため
NULLであった場合SysDateに置き換えるなどの処理を行うと他のカラムがすべて未来日であった場合
不整合は発生する危険性が想定されます。

MIN関数やLEAST関数うまく処理を行おうと考えたのですがなかなか思い浮かばず。
全てのカラム情報を取得し、プログラムのほうで判断することも考えましたが
できるだけSQLで解決したいのですが何か方法はありますでしょうか。
是非、ご助言をよろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

一応動きます、最大の場合は'-infinity'とします。

sql

1create temp table hoge (id int,d1 varchar, d2 varchar,d3 varchar,d4 varchar,d5 varchar); 2 3select id, LEAST( 4 case when length(trim(coalesce(d1,'infinity')))=0 then 'infinity' else d1 end::date, 5 case when length(trim(coalesce(d2,'infinity')))=0 then 'infinity' else d2 end::date, 6 case when length(trim(coalesce(d3,'infinity')))=0 then 'infinity' else d3 end::date, 7 case when length(trim(coalesce(d4,'infinity')))=0 then 'infinity' else d4 end::date, 8 case when length(trim(coalesce(d5,'infinity')))=0 then 'infinity' else d5 end::date 9 ) from hoge; 10

投稿2018/03/05 00:14

A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

least()は、unnestを使用したサブクエリーで、以下のように置き換えることができます。

SQL

1select ( 2 select item 3 from unnest(array[カラム1,カラム2,カラム3]::varchar[]) as w(item) 4 order by item limit 1 5 ) 6from test 7-- order by ~ limit 1 の代わりにmin()でも良い

これに、Nullや空白を除去する条件を加えると、

SQL

1select ( 2 select item 3 from unnest(array[カラム1,カラム2,カラム3]::varchar[]) as w(item) 4 where trim(item)!='' 5 order by item limit 1 6 ) 7from test

となります。
型や条件の変更などはお好きなように。

投稿2018/03/04 17:33

編集2018/03/04 17:41
sazi

総合スコア25206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

どの程度イレギュラーなデータがあるのか提示されていませんが、まず、データクリーニングしましょう。
PostgreSQL 文字列が日付として有効かをチェック が使えそうです。
イレギュラーなデータが多過ぎて修正しきれないなら上長に相談して無効な日付は無視することも考えられます。NULLの扱いも決めておきましょう。
それが済んだら、MINとLEASTを組わせて最少の日付を取得できるでしょう。

通常のテーブル設計では無効な日付が入らないようにDATE型を使います。

投稿2018/03/04 14:54

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

d_11

2018/03/04 15:27

>>通常のテーブル設計では無効な日付が入らないようにDATE型を使います。 ごもっともです。 こちらもその想定でいたのですが....過去流れで...ということらしいです。 画面から入力ということで画面側での制御により ・「YYYY/MM/DD」形式 ・NULLまたは空白(どちらに絞っては欲しいですがどちらも無視でよい) というところまで確認しております。 その他条件は提示されていませんがもし条件が多岐に渡るようであればご教示いただきました内容を活用し条件分岐を反映させ取得させていただきます。 ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問