2016-06-25 3 views
1

У меня есть таблица вроде этого:Как выбрать все строки, которые были вставлены в последний день?

// reset_password_emails 
+----+----------+--------------------+-------------+ 
| id | id_user |  token  | unix_time | 
+----+----------+--------------------+-------------+ 
| 1 | 2353  | 0c274nhdc62b9dc... | 1339412843 | 
| 2 | 2353  | 0934jkf34098joi... | 1339412864 | 
| 3 | 5462  | 3408ujf34o9gfvr... | 1339412894 | 
| 4 | 3422  | 2309jrgv0435gff... | 1339412899 | 
| 5 | 3422  | 34oihfc3lpot4gv... | 1339412906 | 
| 6 | 2353  | 3498hfjp34gv4r3... | 1339412906 | 
| 16 | 2353  | asdf3rf3409kv39... | 1466272801 | 
| 7 | 7785  | 123dcoj34f43kie... | 1339412951 | 
| 9 | 5462  | 3fcewloui493e4r... | 1339413621 | 
| 13 | 8007  | 56gvb45cf3454g3... | 1339424860 | 
| 14 | 7785  | vg4er5y2f4f45v4... | 1339424822 | 
+----+----------+--------------------+-------------+ 

Каждая строка является электронная почта. Теперь я пытаюсь реализовать ограничение на отправку-сброс пароля. Я имею в виду, что пользователь может получать 3 письма в день (не более).

Так мне нужен запрос, чтобы проверить историю пользователя по количеству писем:

SELECT count(1) FROM reset_password_emails WHERE token = :token AND {from not until last day} 

Как я могу осуществить это:

. . . {from now until last day} 

На самом деле я могу сделать это так: NOW() <= (unix_time + 86400) .. Но я думаю, что есть лучший подход, используя interval. Может кто-нибудь сказать мне, что это?

+0

, что у вас есть абсолютно совершенен 'NOW() <= (unix_time + 86400)' –

+0

на «последний день» вы имеете в виду «24 часа до настоящего времени» или «полуночи до полуночи предыдущего день"? – Bohemian

+0

@Bohemian За 24 часа до сегодняшнего дня – stack

ответ

2

Ваше выражение будет работать, но имеет 3 проблемы:

  1. способ, которым вы закодировали это означает, что вычитание должно выполняться для каждой строки (удар производительности)
  2. , потому что вы не используете значение необработанного столбца, вы не можете использовать индекс в столбце времени (если один существовал)
  3. не ясно читать

Попробуйте это:

unix_time > unix_timestamp(subdate(now(), interval '1' day)) 

здесь порог даты и времени рассчитывается раз на запрос, поэтому все вероят лемы выше.

См SQLFiddle demo

+0

Хорошо, как примечание, для этого запроса нужен индекс с несколькими столбцами в '(toke, unix_time)' или два разделенных индекса на столбцах '(token)' и '(unix_time)'? – stack

+0

Только один индекс может использоваться для доступа к таблице, поэтому вам нужен индекс с несколькими столбцами. – Bohemian

+1

Неверно .. Значение столбца 'unix_time' - целое число секунд в таблице выше. Но 'ubdate (now(), interval '1' day)' возвращает формат даты и времени. Таким образом, ваше уравнение не будет работать. – Shafizadeh

1

Вы можете конвертировать ваши функции unix_time используя from_unixtime

select r.* 
    from reset_password_emails r 
where now() <= from_unixtime(r.unix_time) - interval '1' day 

Просто добавьте дополнительные фильтры, которые вы хотите.

Посмотри здесь: http://sqlfiddle.com/#!9/4a7a9/3

Он вычисляет нет строк, потому что ваши данные данные для unix_time поля все с 2011

Edited с sqlfiddle, которые показывают преобразование:

http://sqlfiddle.com/#!9/4a7a9/4

+1

У этого еще есть проблемы 1 и 2, упомянутые в моем ответе – Bohemian

+0

Да, я знаю. Спасибо, что указали. @Bohemian Я просто хотел показать способ сделать это. –

Смежные вопросы