Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: сложение и вычитание времени
 
 автор: u-nick   (20.10.2005 в 23:49)   письмо автору
 
 

Помогите разобраться, почему при запросе "time(ended-came)" иногда проскакивает значение "Null"???

   
 
 автор: cheops   (21.10.2005 в 14:13)   письмо автору
 
   для: u-nick   (20.10.2005 в 23:49)
 

Один из аргументов скорее всего является NULL, а любые операции с NULL приводят к NULL.

   
 
 автор: u-nick   (21.10.2005 в 21:04)   письмо автору
 
   для: cheops   (21.10.2005 в 14:13)
 

Вот реальный пример:

'select Came, Ended, time(ended-came) as Lasting
from Login_4012'

+---------------------+---------------------+----------+
| Came | Ended | Lasting |
+---------------------+---------------------+----------+
| 2005-10-21 10:04:13 | 2005-10-21 10:04:31 | 00:00:18 |
| 2005-10-21 10:04:32 | 2005-10-21 10:05:02 | [NULL] |
| 2005-10-21 10:05:06 | 2005-10-21 10:05:40 | 00:00:34 |
| 2005-10-21 10:05:41 | 2005-10-21 10:05:56 | 00:00:15 |
| 2005-10-21 10:05:55 | 2005-10-21 10:06:24 | [NULL] |
| 2005-10-21 10:06:37 | 2005-10-21 10:07:50 | 00:01:13 |
+---------------------+---------------------+----------+

Ни "Came", ни "Ended" не являются "Null", но Lasting всё равно равен иногда "Null"!

   
 
 автор: cheops   (22.10.2005 в 01:17)   письмо автору
 
   для: u-nick   (21.10.2005 в 21:04)
 

А что даёт запрос
select Came, Ended, Ended - Came as Lasting from Login_4012

   
 
 автор: u-nick   (22.10.2005 в 12:38)   письмо автору
 
   для: cheops   (22.10.2005 в 01:17)
 

Получается простое построчное вычитание, но значения "Null" уже не появляется.
Но мне-то, естественно, простое построчное вычитание не подходит, мне нужен реальный промежуток времени.

P.S. Спасибо, что помогаешь.

   
 
 автор: cheops   (22.10.2005 в 12:44)   письмо автору
 
   для: u-nick   (22.10.2005 в 12:38)
 

А как результат выглядит - нет там отрицательных значений или ещё какой-нибудь бяки?

   
 
 автор: napTu3aH   (22.10.2005 в 12:52)   письмо автору
 
   для: cheops   (22.10.2005 в 12:44)
 

Там есть некоторая закономерность:
если значение полей отличаеться больше чем на минуту, но разнице между временами меньше минуты.
Брррр... Сам не понял что написал. Пример 10:04:32 и 10:05:02. там 04 и 05 минуты, а разница между ними получаетсья (30сек).

P.S. Интересно как Мускул их считает. При простом построчном вычитании если больше минуты он выводит секунды не как 60, а как 100. У него 113 это 1минута 13 сек.

   
 
 автор: u-nick   (22.10.2005 в 12:52)   письмо автору
 
   для: cheops   (22.10.2005 в 12:44)
 

1. 'select Came, Ended, time(ended-came) as Lasting
from Login_4012'

+---------------------+---------------------+----------+
| Came | Ended | Lasting |
+---------------------+---------------------+----------+
| 2005-10-21 10:04:13 | 2005-10-21 10:04:31 | 00:00:18 |
| 2005-10-21 10:04:32 | 2005-10-21 10:05:02 | [NULL] |
| 2005-10-21 10:05:06 | 2005-10-21 10:05:40 | 00:00:34 |
| 2005-10-21 10:05:41 | 2005-10-21 10:05:56 | 00:00:15 |
| 2005-10-21 10:05:55 | 2005-10-21 10:06:24 | [NULL] |
| 2005-10-21 10:06:37 | 2005-10-21 10:07:50 | 00:01:13 |
| 2005-10-21 10:08:06 | 2005-10-21 10:08:20 | 00:00:14 |
+---------------------+---------------------+----------+

2. 'select Came, Ended, Ended - Came as Lasting
from Login_4012'

+---------------------+---------------------+---------+
| Came | Ended | Lasting |
+---------------------+---------------------+---------+
| 2005-10-21 10:04:13 | 2005-10-21 10:04:31 | 18 |
| 2005-10-21 10:04:32 | 2005-10-21 10:05:02 | 70 |
| 2005-10-21 10:05:06 | 2005-10-21 10:05:40 | 34 |
| 2005-10-21 10:05:41 | 2005-10-21 10:05:56 | 15 |
| 2005-10-21 10:05:55 | 2005-10-21 10:06:24 | 69 |
| 2005-10-21 10:06:37 | 2005-10-21 10:07:50 | 113 |
| 2005-10-21 10:08:06 | 2005-10-21 10:08:20 | 14 |
+---------------------+---------------------+---------+

   
 
 автор: cheops   (22.10.2005 в 13:00)   письмо автору
 
   для: u-nick   (22.10.2005 в 12:52)
 

Вообще говоря использовать time() здесь наверное не очень корректно, он ведь принимает в качестве аргумента дату и время суток, а возвращает время суток, в противном случае результат не предсказуем (очень многие функции MySQL возвращают непредсказуемый результат при некорректных начальных значениях)
mysql> SELECT TIME('2003-12-31 01:02:03');
        -> '01:02:03'
mysql> SELECT TIME('2003-12-31 01:02:03.000123');
        -> '01:02:03.000123'

Он же и по другим значениям врёт 113 секунд это никак не 1:13... Он будет врать для всего, что больше минуты, так как временной тип хранится в строке, а разница возвращается в секундах... Т.е. допустим 1256 секунд он запишет как 12:56 и т.д.

   
 
 автор: u-nick   (22.10.2005 в 13:05)   письмо автору
 
   для: cheops   (22.10.2005 в 13:00)
 

И как же мне тогда вообще получить разницу во времени???
Мне это необходимо очень часто

   
 
 автор: cheops   (22.10.2005 в 13:29)   письмо автору
 
   для: u-nick   (22.10.2005 в 13:05)
 

Скорее всего придётся средствами PHP реализовывать эту задачу, хотя посмотрите этот запрос
select Came, Ended, FROM_UNIXTIME(Ended - Came, "%i:%s") as Lasting from Login_4012

   
 
 автор: u-nick   (22.10.2005 в 13:34)   письмо автору
 
   для: cheops   (22.10.2005 в 13:29)
 

Вот что получилось:

+---------------------+---------------------+---------+
| Came | Ended | Lasting |
+---------------------+---------------------+---------+
| 2005-10-21 10:04:13 | 2005-10-21 10:04:31 | 00:18 |
| 2005-10-21 10:04:32 | 2005-10-21 10:05:02 | 01:10 |
| 2005-10-21 10:05:06 | 2005-10-21 10:05:40 | 00:34 |
| 2005-10-21 10:05:41 | 2005-10-21 10:05:56 | 00:15 |
| 2005-10-21 10:05:55 | 2005-10-21 10:06:24 | 01:09 |
| 2005-10-21 10:06:37 | 2005-10-21 10:07:50 | 01:53 |
| 2005-10-21 10:08:06 | 2005-10-21 10:08:20 | 00:14 |
+---------------------+---------------------+---------+

при построчном вычитании 502-432=70 -> 1:10 (вторая строка). В реальности должно получиться просто 00:30

Не понимаю, почему в SQL не продумали такую элементарную вешь!
А PHP я вообще не знаю (по крайней мере пока).

Может ещё какие идеи появятся?

   
 
 автор: cheops   (22.10.2005 в 13:39)   письмо автору
 
   для: u-nick   (22.10.2005 в 13:34)
 

Ну, помоему, то что нужно... А в смысле на две части?

   
 
 автор: u-nick   (22.10.2005 в 13:41)   письмо автору
 
   для: cheops   (22.10.2005 в 13:39)
 

Посмотри, пожалуйста, ещё раз предыдущюю мою запись я её немного изменил во время твоего ответа.

   
 
 автор: cheops   (22.10.2005 в 13:53)   письмо автору
 
   для: u-nick   (22.10.2005 в 13:41)
 

Давайте ещё одну попытку произведём
SELECT Came, Ended, FROM_UNIXTIME(UNIX_TIMESTAMP(Ended) - UNIX_TIMESTAMP(Came), "%i:%s")  as Lasting FROM Login_4012

Хотя мне уже эта гроздь функций не по душе :)))

   
 
 автор: u-nick   (22.10.2005 в 14:06)   письмо автору
 
   для: cheops   (22.10.2005 в 13:53)
 

ГЕНИАЛЬНО!!!!!!!!!!!!!!!!!!!!!!!!!

Спасибо огромное!!!

   
 
 автор: u-nick   (22.10.2005 в 14:36)   письмо автору
 
   для: u-nick   (22.10.2005 в 14:06)
 

А можно ещё тебя помучить?

Как сделать сумму и среднее значение столбца 'Lasting'?
1. sum(Lasting) и avg(Lasting) - не подходят
Более того, 2. 'from_unixtime(sum(Lasting), "%i:%s") as Total_time'
и 'from_unixtime(avg(Lasting), "%i:%s") as Avg_time тоже не подходят, т.к. суммирование Lasting происходит как-то странно (получается всего 180 в первом случае и 3:00 во втором, когда должно получиться 251 минут).

   
 
 автор: cheops   (22.10.2005 в 22:31)   письмо автору
 
   для: u-nick   (22.10.2005 в 14:36)
 

нет, наверное придётся скармливать всё выражение, т.е. писать MAX(FROM_UNIXTIME(UNIX_TIMESTAMP(Ended) - UNIX_TIMESTAMP(Came)) и тоже самое с AVG().

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования