2017-08-30 4 views
0

私は非常にpostgresで新しく、私はここに投稿する前に約1時間これを検索してきました。Postgres:タイムスタンプ上の特定の日付のクエリは、私のpostgresクライアントのデータを見ることができる間にデータを返しません。

うまくいけば、これはおそらく些細な問題で私を助けることができます。

私は時間のために、すべてのデータを取得するために照会する
CREATE TABLE LTC (
     id  SERIAL PRIMARY KEY, 
     time  timestamptz, 
     side  CHAR(4), 
     price REAL, 
     v  REAL, 
     n  INT 
    ); 

=「2017-08-12T03:58:26.563Z」(ISO文字列

私は、このスキーマで作成されたデータベースLTCを持っていますjavascriptから)。私はその時間にデータベースに100行以上のデータがあることを知っています。私はpostgresクライアントでそれを見ています。ここで

は、私は、クエリやってるさ:

select * from LTC where time = '2017-08-12T03:58:26.563Z'::timestamptz 

なぜ私は結果を取得していないのですか?


編集は:

それでもわからないなぜそれが働いていなかったが、私は書いた回避策を行います。JavaScriptで

var date = new Date('2017-08-12T03:58:26.563Z').toISOString(); // actual time passed as parameter in my function, hard-coded for the example 
var reg  = new RegExp("([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})\.[0-9]*Z","gmi"); 
var start = date.replace(reg, function(match,year,month,day,hour,min,sec,ms) { 
    return year+'-'+month+'-'+day+'T'+hour+':'+min+':00.000Z'; 
}); 
var end  = date.replace(reg, function(match,year,month,day,hour,min,sec,ms) { 
    var min = parseInt(min)+1; 
    if (min<=9) { 
     min = '0'+min; 
    } 
    return year+'-'+month+'-'+day+'T'+hour+':'+min+':00.000Z'; 
}); 

var query = "select * from LTC where time >= '"+start+"'::timestamptz and time < '"+end+"'::timestamptz"; // This works 

答えて

1

は使用してみてくださいをdate_trunc('second',timestamp)の両方で数値精度があなたを捨てているものでないことを確認してください。クライアントが表示していない小数点以下の桁があり、平等を放棄している可能性があります。

数値平等の問題を避けるために、もう1つの解決策が範囲(between x and y)を与えています。

使用しているデータでテストできるように、表示されているデータの正確なコピーを得ることができれば助かります(ご存知の方ならおそらくpg_dumpを使用してください)。

最後に確認したいことは、参照しているタイムゾーンが明示的に記載されていることです。私は一般的にtimestamp without time zoneを使用してこの問題を回避していますが、タイムゾーンを異なる値に自動設定すると、あなたも迷惑をかける可能性があります。私はあなたの行動を再現しようとするテストを構築してい

CREATE TABLE LTC (
id serial 
, time timestamptz 
); 

INSERT INTO LTC (time) 
values ('2017-08-12T03:58:26.56312345'::timestamptz) 
returning *; 

select * 
from LTC 
where time = '2017-08-12T03:58:26.563Z'::timestamptz 
; 

select *, l.time = p.ts as test 
from LTC l, (select '2017-08-12T03:58:26.563Z'::timestamptz as ts) p 
; 

私は何をテストする良い方法は、2つの値を選択することで

select *, l.time = p.ts as test 
from LTC l, (select '2017-08-12T03:58:26.563Z'::timestamptz as ts) p 
; 

EDITのようなものです実際にここに来る:

1;"2017-08-12 03:58:26.563123-04";"2017-08-11 23:58:26.563-04";f 

うまくいけばあなたca n何が起きているのかを確認してください。'2017-08-12T03:58:26.563Z'::timestamptzはUTC時間として解釈され、その後私のタイムゾーン(UTC-04)に変換されるので、実際には比較されるのはの日付です!将来、このタイプの平等を並べて表示することは、自分が思っていることを実行していることをテストするための素晴らしい方法です(特に、自動変換が頻繁に行われる日付/時刻の場合)。

+0

なぜそれが動作していないのか分かりませんが、私はあなたのレンジソリューションを試してみました。私は、クエリを生成するためにJSコードを投稿しました。 –

+0

それは痛いJSスクリプトです!必要なものが分かりやすい場合は、代わりにこれをDB側のロジックとして試してみてください。 'select * LTC からdate_trunc( 'minute'、time :: timestamp)= date_trunc( 'minute'、 ' 2017-08-12T03:58:26.563Z ':: timestamp); '。 'timestamp'にキャストすると、タイムゾーンを明示的に渡していない場合に、' timestamptz'を使って自動変換の問題を解決しているようです。 – cole

関連する問題