3

DATETIMEmySQL(fromStamp)に有効な日付/タイムスタンプのあるフィールドがあります。分を次の6分間隔に切り上げることができる必要があります。秒は無視するか、:00として扱う必要があります

したがって、私のDATETIMEが :00と:06の間、および:31と:36の間の時間を除いて2013-01-31 13:07:17、結果を切り捨てる必要がある場合は、それらを切り捨てる必要があります。2013-01-31 13:12:00

 :00-06 round DOWN to 00
 :07-12 round UP to 12
 :13-18 round UP to 18
 :19-24 round UP to 24
 :24-30 round UP to 30
 :31-36 round DOWN to 30
 :37-42 round UP to 42
 :43-48 round UP to 48
 :49-54 round UP to 54
 :55-00 round UP to 00

以下を使用して選択的に切り捨てる合理的な方法を見つけました。

SELECT
  fromStamp, 
  CONCAT(DATE_FORMAT(`fromStamp`, '%Y-%m-%d'), ' ',
         SEC_TO_TIME((TIME_TO_SEC(`fromStamp`) DIV 360) * 360))
FROM `table` 
WHERE (
    DATE_FORMAT(`fromStamp`, '%i') BETWEEN 0 AND 6 
    OR DATE_FORMAT(`fromStamp`, '%i') BETWEEN 31 AND 36
);

他のすべてを次の6分間隔に切り上げる良い方法はありますか?(私は何か単純なものが欠けているような気がします)

アップデート

だから私は@mellamokbの解決策を使っていますが、秒に関する彼のコメントは正しいです、それは効果を発揮します。

2013-01-22 12:24:13のDATETIMEは12:30に切り上げられますが、これは必要なものではないため、最初に次のことを行います。

UPDATE table SET fromStamp = CONCAT(DATE_FORMAT(fromStamp, '%Y-%m-%d %h:%i'), ':00'); 

秒を取り除くために、それから私が探しているものを正確に取得する彼のクエリ。

4

3 に答える 3

2

切り上げは1、次に近い6-minute間隔にシフトするために追加することを除いて、非常によく似たロジックです。1また、補正係数としてから減算しました。それ以外の場合、次の6分間隔でシフトアップするTIME_TO_SECなどの境界値、つまり。06:0012:00

SEC_TO_TIME( ( (TIME_TO_SEC(`fromStamp`) - 1) DIV 360 + 1) * 360))
                                                      ^^^ add one

2つを組み合わせるには、CASEステートメントを使用して、レコードごとに使用される丸めの形式を制御します。

SELECT
  fromStamp, 
  CASE WHEN
    DATE_FORMAT(`fromStamp`, '%i') BETWEEN 0 AND 6 
    OR DATE_FORMAT(`fromStamp`, '%i') BETWEEN 31 AND 36
  THEN
    CONCAT(DATE_FORMAT(`fromStamp`, '%Y-%m-%d'), ' ',
         SEC_TO_TIME((TIME_TO_SEC(`fromStamp`) DIV 360) * 360))
  ELSE
    CONCAT(DATE_FORMAT(`fromStamp`, '%Y-%m-%d'), ' ',
         SEC_TO_TIME(((TIME_TO_SEC(`fromStamp`) - 1) DIV 360 + 1) * 360))
  END
FROM `table`

デモ

于 2013-01-31T13:48:30.320 に答える
1

提供された基準に基づいて、この奇妙なタイプの丸めを処理する最も簡単な方法は次のとおりだと思います。

 SELECT `fromStamp`
      , DATE_FORMAT(`fromStamp`,'%Y-%m-%d %H') + INTERVAL
        CASE
            WHEN TIME_FORMAT(`fromStamp`,'%i') <=  6 THEN  0  -- round DOWN
            WHEN TIME_FORMAT(`fromStamp`,'%i') <= 12 THEN 12  -- round up
            WHEN TIME_FORMAT(`fromStamp`,'%i') <= 18 THEN 18  -- round up
            WHEN TIME_FORMAT(`fromStamp`,'%i') <= 24 THEN 24  -- round up
         -- WHEN TIME_FORMAT(`fromStamp`,'%i') <= 30 THEN 30  -- round up
            WHEN TIME_FORMAT(`fromStamp`,'%i') <= 36 THEN 30  -- round DOWN
            WHEN TIME_FORMAT(`fromStamp`,'%i') <= 42 THEN 42  -- round up
            WHEN TIME_FORMAT(`fromStamp`,'%i') <= 48 THEN 48  -- round up
            WHEN TIME_FORMAT(`fromStamp`,'%i') <= 54 THEN 54  -- round up
            WHEN TIME_FORMAT(`fromStamp`,'%i') >= 55 THEN 60  -- round up
        END MINUTE AS rnd_fromStamp

これは、ステートメントを見て「そのステートメントがfromStampに対してをしているのか」と疑問に思う将来のレビュー担当者にとって、何が起こっているかを表現する最も簡単な方法のようです。

少し速い(より効率的な)アルゴリズムがあるかもしれませんが、これほどエレガントで、読みやすく、理解しやすいアルゴリズムはないと思います。

于 2013-01-31T14:40:40.920 に答える
0

これは私が分までの切り上げに使用しました

SELECT MINUTE(SEC_TO_TIME(((TIME_TO_SEC(call_duration))DIV 60 +1)* 60))call_duration FROM call_log

于 2015-03-26T06:56:56.183 に答える