id | start_time | period_ytpe | period_value |
---|---|---|---|
1 | 1461427200 | day | 3 |
2 | 1461427200 | month | 2 |
如上表,start_time
表示开始时间,period_ytpe
表示期限类型,period_value
表示期限值,
第一第记录表是 3天
,第二条表示2个月
如果查询出,从start_time
开始,期限在今天之前的记录
比如:
第一条,start_time开始, 三天后的时间戳,如果是在今天(2016-06-04)之前,则是满足条件!
第二条,start_time开始, 两个月后的时间戳,如果是在今天(2016-06-04)之前,则是满足条件!
____________________________________分割线_________________________________________
感谢各位的回答,在不改数据库的情况下(数据表已经被很多地方引用,且不是我设计),我自己写了一条SQL,做了几步转换,感觉性能不会好,但好像可以用了,还好这个表数据量不大,每天最多新增一条新记录。
把开始
start_time
转为date
,再DATE_ADD
加上 日或者月,得到时间再转为unix_time
用今天凌晨 UNIX_TIMESTAMP(CURDATE())减去 上面得到的时候,如果结果大于 0,那就是想要的结果
SELECT `id`,`name`,
CASE `period_type`
WHEN 'day'
THEN UNIX_TIMESTAMP(CURDATE())-UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME(`start_time`),INTERVAL period_value day))
WHEN 'month'
THEN UNIX_TIMESTAMP(CURDATE())-UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME(`start_time`),INTERVAL period_value month))
ELSE ''
END AS 'time_interval'
FROM `table`
WHERE `xxxxxxx'
HAVING time_interval>0
ORDER BY time_interval desc
迷茫2017-04-17 14:55:10
あなたがどの言語を使っているのかわかりません。
最も愚かな方法を使用してください~~
まず、あなたの言語で今日のタイムスタンプを取得します。例: 1465056000
SELECT * FROM `table` WHERE `period_ytpe` = 'day' AND `start_time` + 86400*`period_value` < 1465056000
連合
SELECT * FROM `table` WHERE `period_ytpe` = 'month' AND `start_time` + 86400*30*`period_value` <1465056000
もちろん、欠点は、デフォルトでは月に 30 日間、あなたが彼になることになるということです。
mysqlを使って計算したい場合。 。次に、start_time を時間タイプとして保存します。 。次に、date_add を使用して計算します。
そして余談です。 。テーブルを設計するときに end_time だけを計算してみてはいかがでしょうか?フィルタリング時にこれを使用する必要がある場合、計算タイプによってインデックスのエラーが発生し、非常に悪いことになります。さまざまなメータースキャン
PHPz2017-04-17 14:55:10
タイム ストレージでは、フィールドを数値型のタイムスタンプではなくタイムスタンプまたは日時型に設定することをお勧めします。
まず第一に、数値型のタイムスタンプは SQL でのクエリには不便であり、コードでも変換する必要があります。
>数値型 SQL の関連関数は使用できません。計算前に数値型のタイムスタンプをタイムスタンプ型または日時型に変換する必要があります。
タイムスタンプまたは日付時刻の場合、date_add 関数を使用して、時間要件を満たすように時間を増減できます。
http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-add
たとえば
t から date_add(start_time、間隔 1 日) を選択
start_time に 1 日追加します
黄舟2017-04-17 14:55:10
質問を明確にするには、start_time を特定の日または月以降のタイムスタンプにする必要があります。
アイデア: 現在の時刻を日付形式に変換し、取得する日または月の値に日付を追加して、結果をタイムスタンプに変換します
date_add(date,interval n exp)
date が日付時刻形式であり、変換する必要があるタイムスタンプの場合、exp は
SECOND 秒 SECONDS MINUTE 分 MINUTES HOUR time HOURS DAY days DAYS MONTH months MONTHS
YEAR year YEARS MINUTE_SECOND 分、および秒 "MINUTES:SECONDS" HOUR_MINUTE 時と分 "HOURS:MINUTES"
DAY_HOUR 日と時 "DAYS HOURS" YEAR_MONTH 年と月 "YEARS-MONTHS"
HOUR_SECOND 時、分、 "HOURS:MINUTES:SECONDS" DAY_MINUTE 日、時、分 "DAYS HOURS:MINUTES" DAY_SECOND 日、時、分、秒 "DAYS HOURS:MINUTES:SECONDS"
1. start_time から 3 日後のタイムスタンプ:
MYSQL コードは次のとおりです。
select UNIX_TIMESTAMP(date_add(FROM_UNIXTIME(start_time), 間隔 3 日)) from t
3 は追加する日数を表します。T をデータベース内の任意のテーブルに置き換えて、
2 の start_time からのタイムスタンプ N か月を実行します。
select UNIX_TIMESTAMP(date_add(FROM_UNIXTIME(start_time), 間隔 3 MONTH)) from t
この関数は MYSQL 用です。他のデータベースにも対応する関数がありますが、テストされていません。
大家讲道理2017-04-17 14:55:10
書いてみましたが失敗しました。
予想される SQL:
SELECT * FROM テーブル
WHERE start_time < UNIX_TIMESTAMP(DATE_SUB(CURRENT_DATE, INTERVAL `period_value` `period_type`));
結果として、上記の SQL 構文は正しくありません。
より近い SQL:
SELECT * FROM テーブル
WHERE start_time < UNIX_TIMESTAMP(DATE_SUB(CURRENT_DATE, INTERVAL `period_value` DAY));
ただし、これには period_type
フィールドは必要ありません。
実際、@lyt8384 が述べたように、SQL ステートメントで不適切な操作を使用するとインデックスが無効になり、それに応じてクエリ効率も低下します。
テーブル構造を変更する権限がある場合は、end_time
フィールド、end_time (unit: s)=start_time + period_type * period_value
を追加してから、< code> end_time フィールドにはインデックスが付けられていますが、これはより良いはずです。