11

私はHiveで作業しており、次のような構造のテーブルを持っています:

CREATE TABLE t1 (
  id INT,
  created TIMESTAMP,
  some_value BIGINT
);

t1180 日未満のすべての行を見つける必要があります。次のクエリは、検索述語に一致するデータがテーブルに存在する場合でも、行を生成しません。

select * 
from t1 
where created > date_sub(from_unixtime(unix_timestamp()), 180);

Hiveで日付比較を実行する適切な方法は何ですか?

4

5 に答える 5

14

どうですか:

where unix_timestamp() - created < 180 * 24 * 60 * 60

日付の計算は、実際のタイムスタンプ値を使用して行うことができれば、通常最も簡単です。

それとも丸一日だけカットしたいですか?次に、問題は、int と文字列の間を行ったり来たりする方法にあると思います。試す:

where created > unix_timestamp(date_sub(from_unixtime(unix_timestamp(),'yyyy-MM-dd'),180),'yyyy-MM-dd')

各 UDF を見ていく:

  1. unix_timestamp()int を返します: エポックからの現在の時間 (秒)
  2. from_unixtime(,'yyyy-MM-dd')'2012-12-28' など、指定された形式の文字列に変換します
  3. date_sub(,180)その文字列から 180 日を減算し、同じ形式で新しい文字列を返します。
  4. unix_timestamp(,'yyyy-MM-dd')その文字列を int に変換します

あまりにも面倒な場合は、いつでも UDF を記述して自分で行うことができます。

于 2012-12-28T17:54:33.510 に答える
6

または、 datediffを使用することもできます。
次に、文字列タイムスタンプ (jdbc 形式) の場合、where 句は次のようになります。

datediff(from_unixtime(unix_timestamp()), created) < 180;

Unix エポック時間の場合:

datediff(from_unixtime(unix_timestamp()), from_unixtime(created)) < 180;
于 2012-12-29T00:55:55.647 に答える
3

タイムスタンプ型を扱うHiveのバグだと思います。私は最近それを使用しようとしていて、間違った結果を得ています。タイムスタンプの代わりに文字列を使用するようにスキーマを変更し、

yyyy-MM-dd HH:mm:ss

形式、その後、選択クエリが機能しました。

ドキュメントによると、Hive はエポック秒を表す BIGINT をタイムスタンプに変換できる必要があり、既存のすべての日時 UDF はタイムスタンプ データ型で機能する必要があります。

この単純なクエリで:

select from_unixtime(unix_timestamp()), cast(unix_timestamp() as timestamp) from test_tt limit 1;

両方のフィールドが同じであることを期待しますが、次のようになります。

2012-12-29 00:47:43 1970-01-16 16:52:22.063

他にも異変が見られます。

于 2012-12-29T00:52:46.353 に答える
1

これを確認し、Hiveで15分未満の日付の違いを参照した後、解決策を思いつきました。Hiveが文字列としての日付に対して効果的に比較を実行しない理由はわかりませんが(辞書式順序で並べ替えて比較する必要があります)、次の解決策が機能します。

FROM (
    SELECT  id, value,
            unix_timestamp(created) c_ts, 
            unix_timestamp(date_sub(from_unixtime(unix_timestamp()), 180), 'yyyy-MM-dd') c180_ts
    FROM    t1
) x
JOIN t1 t ON x.id = t.id
SELECT  to_date(t.Created), 
        x.id, AVG(COALESCE(x.HighestPrice, 0)), AVG(COALESCE(x.LowestPrice, 0))
WHERE   unix_timestamp(t.Created) > x.c180_ts
GROUP BY to_date(t.Created), x.id ;
于 2012-12-28T16:54:29.000 に答える