Получить данные за определенный промежуток времени - PullRequest
0 голосов
/ 02 октября 2018

Я пытаюсь выбрать записи с 7 часов вечера до 7 часов утра с 2018-09-24 до 2018-09-26 для каждого дня.
пример:

2018-09-С 24:00 до 7:00 до 07:00 2018-09-25
2018-09-25 _____ с 7:00 до 7:00 2018-09-26
2018-09-26 _____ с 7:00 до 7:00 2018-09-27

с использованием этого кода A: Я получаю записи с 7 вечера (2018-09-24) до 7 утра (2018-09-26).

If Trim(cbShift.Text) = "Morning" Then
startdt = (S_date.Text) & " 19:00:00.317"
enddt = (E_date.Text) & " 07:00:00.160" End If
SELECT FROM tb_test
WHERE  (DateCreate   BETWEEN convert(datetime,@startdt) AND convert(datetime,@enddt))

и используя этот код B:

WHERE  DateCreate > convert(datetime,'2018-09-24') AND DateCreate <=
DATEADD(day,1,convert(datetime,'2018-09-26'))
AND (DATEPART(hh,DateCreate) >= 19 and DATEPART(hh,DateCreate) <= 24  )

or DateCreate > convert(datetime,'2018-09-24') AND DateCreate <=
DATEADD(day,1,convert(datetime,'2018-09-26'))
AND (DATEPART(hh,DateCreate) >= 0 and DATEPART(hh,DateCreate) <= 6  )

Я получаю

2018-09-24 (00-> 7 и 19 ->24), 2018-09-25 (00-> 7 и 19 -> 24) и 2018-09-26 (00-> 7 и 19 -> 24)

Есть ли способЯ могу сделать, чтобы получить данные в точности, как мой пример выше.Спасибо за вашу помощь

Ответы [ 3 ]

0 голосов
/ 02 октября 2018

Другой способ взглянуть на проблему - сказать, что вы хотите, чтобы DateCreate -12 часов были между 7 утра и 7 вечера в интересующие дни.Итак, попробуйте это (заметьте, мы не добавляем время к startdt и enddt):

If Trim(cbShift.Text) = "Morning" Then
startdt = (S_date.Text)
enddt = (E_date.Text) End If
SELECT FROM tb_test
WHERE DateCreate - INTERVAL 12 HOUR BETWEEN CONVERT(DATETIME,@startdt) AND CONVERT(DATETIME,@enddt) AND
      TIME(DateCreate - INTERVAL 12 HOUR) BETWEEN '07:00:00' AND '19:00:00'
0 голосов
/ 02 октября 2018

Давайте создадим несколько тестовых данных:

mysql> create table t (id int auto_increment, stamp datetime, primary key (id));
Query OK, 0 rows affected (0.46 sec)

mysql> insert into t (stamp) values
    ->   ('2018-09-24 18:59:59'), ('2018-09-24 19:00:00'), ('2018-09-24 19:00:01'),
    ->   ('2018-09-25 06:59:59'), ('2018-09-25 07:00:00'), ('2018-09-25 07:00:01'),
    ->   ('2018-09-25 18:59:59'), ('2018-09-25 19:00:00'), ('2018-09-25 19:00:01'),
    ->   ('2018-09-26 06:59:59'), ('2018-09-26 07:00:00'), ('2018-09-26 07:00:01'),
    ->   ('2018-09-26 18:59:59'), ('2018-09-26 19:00:00'), ('2018-09-26 19:00:01'),
    ->   ('2018-09-27 06:59:59'), ('2018-09-27 07:00:00'), ('2018-09-27 07:00:01');
Query OK, 18 rows affected (0.00 sec)
Records: 18  Duplicates: 0  Warnings: 0

mysql> select * from t;
+----+---------------------+
| id | stamp               |
+----+---------------------+
|  1 | 2018-09-24 18:59:59 |
|  2 | 2018-09-24 19:00:00 |
|  3 | 2018-09-24 19:00:01 |
|  4 | 2018-09-25 06:59:59 |
|  5 | 2018-09-25 07:00:00 |
|  6 | 2018-09-25 07:00:01 |
|  7 | 2018-09-25 18:59:59 |
|  8 | 2018-09-25 19:00:00 |
|  9 | 2018-09-25 19:00:01 |
| 10 | 2018-09-26 06:59:59 |
| 11 | 2018-09-26 07:00:00 |
| 12 | 2018-09-26 07:00:01 |
| 13 | 2018-09-26 18:59:59 |
| 14 | 2018-09-26 19:00:00 |
| 15 | 2018-09-26 19:00:01 |
| 16 | 2018-09-27 06:59:59 |
| 17 | 2018-09-27 07:00:00 |
| 18 | 2018-09-27 07:00:01 |
+----+---------------------+
18 rows in set (0.00 sec)

Теперь мы хотим выбрать из 2018-09-24 19:00:00 до 2018-09-25 07:00:00:

mysql> select * from t where stamp between (@start := '2018-09-24 19:00:00') and date_add(@start, interval 12 hour);
+----+---------------------+
| id | stamp               |
+----+---------------------+
|  2 | 2018-09-24 19:00:00 |
|  3 | 2018-09-24 19:00:01 |
|  4 | 2018-09-25 06:59:59 |
|  5 | 2018-09-25 07:00:00 |
+----+---------------------+
4 rows in set (0.01 sec)

Если мы хотим включить 3 дняЦенность данных во время этих окон, мы можем сделать это, используя UNION ALL:

mysql> select * from t where stamp between (@start := '2018-09-24 19:00:00') and date_add(@start, interval 12 hour)
    -> union all select * from t where stamp between (@start := '2018-09-25 19:00:00') and date_add(@start, interval 12 hour)
    -> union all select * from t where stamp between (@start := '2018-09-26 19:00:00') and date_add(@start, interval 12 hour);
+----+---------------------+
| id | stamp               |
+----+---------------------+
|  2 | 2018-09-24 19:00:00 |
|  3 | 2018-09-24 19:00:01 |
|  4 | 2018-09-25 06:59:59 |
|  5 | 2018-09-25 07:00:00 |
|  8 | 2018-09-25 19:00:00 |
|  9 | 2018-09-25 19:00:01 |
| 10 | 2018-09-26 06:59:59 |
| 11 | 2018-09-26 07:00:00 |
| 14 | 2018-09-26 19:00:00 |
| 15 | 2018-09-26 19:00:01 |
| 16 | 2018-09-27 06:59:59 |
| 17 | 2018-09-27 07:00:00 |
+----+---------------------+
12 rows in set (0.00 sec)

И вот как это делается.

Отредактировано, чтобы добавить: После просмотра ответа Ника, который использует TIME()это действительно более чистое решение:

mysql> select * from t where date(stamp) between '2018-09-24' and '2018-09-27'
    -> and time(stamp + interval 12 hour) between '07:00:00' and '19:00:00';
+----+---------------------+
| id | stamp               |
+----+---------------------+
|  2 | 2018-09-24 19:00:00 |
|  3 | 2018-09-24 19:00:01 |
|  4 | 2018-09-25 06:59:59 |
|  5 | 2018-09-25 07:00:00 |
|  8 | 2018-09-25 19:00:00 |
|  9 | 2018-09-25 19:00:01 |
| 10 | 2018-09-26 06:59:59 |
| 11 | 2018-09-26 07:00:00 |
| 14 | 2018-09-26 19:00:00 |
| 15 | 2018-09-26 19:00:01 |
| 16 | 2018-09-27 06:59:59 |
| 17 | 2018-09-27 07:00:00 |
+----+---------------------+
12 rows in set (0.00 sec)
0 голосов
/ 02 октября 2018

Я думаю, что проблема с порядком оценки в вашем предложении WHEREвсегда использую скобки вокруг OR операторов в SQL.Следующие работы на MySQL 5.6.

SELECT * 
FROM tb_test
WHERE  datecreate between '2018-09-24 19:00:00' and '2018-09-26 07:00:00'
AND (hour(DateCreate) >= 19 or hour(DateCreate) < 7);

Для справки, я использовал эту схему тестирования:

CREATE table tb_test
(datecreate datetime);

CREATE OR REPLACE VIEW generator_16
AS SELECT 0 n UNION ALL SELECT 1  UNION ALL SELECT 2  UNION ALL 
 SELECT 3   UNION ALL SELECT 4  UNION ALL SELECT 5  UNION ALL
 SELECT 6   UNION ALL SELECT 7  UNION ALL SELECT 8  UNION ALL
 SELECT 9   UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL
 SELECT 12  UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL 
 SELECT 15;

CREATE OR REPLACE VIEW generator_256
AS SELECT ( ( hi.n << 4 ) | lo.n ) AS n
 FROM generator_16 lo, generator_16 hi;

INSERT INTO tb_test
SELECT date_add("2018-09-24",interval n hour)
FROM generator_256;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...