Nano Hash - криптовалюты, майнинг, программирование

Получите список дат между двумя датами

Используя стандартные функции mysql, можно написать запрос, который вернет список дней между двумя датами.

например, для данных 2009-01-01 и 2009-01-13 он вернет таблицу с одним столбцом со значениями:

 2009-01-01 
 2009-01-02 
 2009-01-03
 2009-01-04 
 2009-01-05
 2009-01-06
 2009-01-07
 2009-01-08 
 2009-01-09
 2009-01-10
 2009-01-11
 2009-01-12
 2009-01-13

Изменить: похоже, я не был ясен. Я хочу СОЗДАТЬ этот список. У меня есть значения, хранящиеся в базе данных (по дате и времени), но я хочу, чтобы они были агрегированы в левом внешнем соединении со списком дат, как указано выше (я ожидаю null с правой стороны некоторых из этого соединения в течение нескольких дней и буду обрабатывать это ).



Ответы:


1

Я бы использовал эту хранимую процедуру для генерации необходимых интервалов в таблице temp с именем time_intervals, а затем JOIN и агрегирования вашей таблицы данных с таблицей temp time_intervals.

Процедура может генерировать интервалы всех различных типов, которые вы видите в ней:

call make_intervals('2009-01-01 00:00:00','2009-01-10 00:00:00',1,'DAY')
.
select * from time_intervals  
.
interval_start      interval_end        
------------------- ------------------- 
2009-01-01 00:00:00 2009-01-01 23:59:59 
2009-01-02 00:00:00 2009-01-02 23:59:59 
2009-01-03 00:00:00 2009-01-03 23:59:59 
2009-01-04 00:00:00 2009-01-04 23:59:59 
2009-01-05 00:00:00 2009-01-05 23:59:59 
2009-01-06 00:00:00 2009-01-06 23:59:59 
2009-01-07 00:00:00 2009-01-07 23:59:59 
2009-01-08 00:00:00 2009-01-08 23:59:59 
2009-01-09 00:00:00 2009-01-09 23:59:59 
.
call make_intervals('2009-01-01 00:00:00','2009-01-01 02:00:00',10,'MINUTE')
. 
select * from time_intervals
.  
interval_start      interval_end        
------------------- ------------------- 
2009-01-01 00:00:00 2009-01-01 00:09:59 
2009-01-01 00:10:00 2009-01-01 00:19:59 
2009-01-01 00:20:00 2009-01-01 00:29:59 
2009-01-01 00:30:00 2009-01-01 00:39:59 
2009-01-01 00:40:00 2009-01-01 00:49:59 
2009-01-01 00:50:00 2009-01-01 00:59:59 
2009-01-01 01:00:00 2009-01-01 01:09:59 
2009-01-01 01:10:00 2009-01-01 01:19:59 
2009-01-01 01:20:00 2009-01-01 01:29:59 
2009-01-01 01:30:00 2009-01-01 01:39:59 
2009-01-01 01:40:00 2009-01-01 01:49:59 
2009-01-01 01:50:00 2009-01-01 01:59:59 
.
I specified an interval_start and interval_end so you can aggregate the 
data timestamps with a "between interval_start and interval_end" type of JOIN.
.
Code for the proc:
.
-- drop procedure make_intervals
.
CREATE PROCEDURE make_intervals(startdate timestamp, enddate timestamp, intval integer, unitval varchar(10))
BEGIN
-- *************************************************************************
-- Procedure: make_intervals()
--    Author: Ron Savage
--      Date: 02/03/2009
--
-- Description:
-- This procedure creates a temporary table named time_intervals with the
-- interval_start and interval_end fields specifed from the startdate and
-- enddate arguments, at intervals of intval (unitval) size.
-- *************************************************************************
   declare thisDate timestamp;
   declare nextDate timestamp;
   set thisDate = startdate;

   -- *************************************************************************
   -- Drop / create the temp table
   -- *************************************************************************
   drop temporary table if exists time_intervals;
   create temporary table if not exists time_intervals
      (
      interval_start timestamp,
      interval_end timestamp
      );

   -- *************************************************************************
   -- Loop through the startdate adding each intval interval until enddate
   -- *************************************************************************
   repeat
      select
         case unitval
            when 'MICROSECOND' then timestampadd(MICROSECOND, intval, thisDate)
            when 'SECOND'      then timestampadd(SECOND, intval, thisDate)
            when 'MINUTE'      then timestampadd(MINUTE, intval, thisDate)
            when 'HOUR'        then timestampadd(HOUR, intval, thisDate)
            when 'DAY'         then timestampadd(DAY, intval, thisDate)
            when 'WEEK'        then timestampadd(WEEK, intval, thisDate)
            when 'MONTH'       then timestampadd(MONTH, intval, thisDate)
            when 'QUARTER'     then timestampadd(QUARTER, intval, thisDate)
            when 'YEAR'        then timestampadd(YEAR, intval, thisDate)
         end into nextDate;

      insert into time_intervals select thisDate, timestampadd(MICROSECOND, -1, nextDate);
      set thisDate = nextDate;
   until thisDate >= enddate
   end repeat;

 END;

Аналогичный пример сценария данных в нижней части этот пост, в котором я создал аналогичную функцию для SQL Server.

04.02.2009
  • Я лично надеялся на нечто подобное сгенерированным последовательностям в PostgreSQL. 20.10.2011
  • Если вы генерируете данные один раз, вы даже можете использовать постоянные таблицы и использовать этот скрипт для заполнения недостающих дат. 20.01.2015
  • Мне пришлось изменить разделитель перед оператором процедуры создания, чтобы он работал через phpMyAdmin (чтобы избежать синтаксической ошибки в операторах объявления) [код] DECLARE // [/ код] 01.12.2016
  • Это решение очень мощное и гибкое, но, к сожалению, на mariaDB я получаю сообщение об ошибке # 1067 - Недопустимое значение по умолчанию для 'interval_end' при выполнении вызова make_interval ('2009-01-01 00:00:00', '2009-01-10 00: 00: 00 ', 1,' ДЕНЬ '); У меня версия 5.7.28 13.06.2020

  • 2

    Для MSSQL вы можете использовать это. Это ОЧЕНЬ быстро.

    Вы можете обернуть это в табличную функцию или сохраненную процедуру и проанализировать даты начала и окончания как переменные.

    DECLARE @startDate DATETIME
    DECLARE @endDate DATETIME
    
    SET @startDate = '2011-01-01'
    SET @endDate = '2011-01-31';
    
    WITH dates(Date) AS 
    (
        SELECT @startdate as Date
        UNION ALL
        SELECT DATEADD(d,1,[Date])
        FROM dates 
        WHERE DATE < @enddate
    )
    
    SELECT Date
    FROM dates
    OPTION (MAXRECURSION 0)
    GO
    

    Редактировать 2021/01 (д-р V): мне понравилось это решение, и я заставил его работать для mySQL V8. Вот код, превращающий его в процедуру:

    DELIMITER //
    
    CREATE PROCEDURE dates_between (IN from_date DATETIME,
                                   IN to_date DATETIME) BEGIN
        WITH RECURSIVE dates(Date) AS
        (
            SELECT from_date as Date
            UNION ALL
            SELECT DATE_ADD(Date, INTERVAL 1 day) FROM dates WHERE Date < to_date
        )
        SELECT DATE(Date) FROM dates;
    END//
    
    DELIMITER ;
    
    18.11.2011
  • Какая здесь польза от OPTION (MAXRECURSION 0)? 11.07.2016

  • 3

    Вы можете использовать пользовательские переменные в MySQL следующим образом:

    SET @num = -1;
    SELECT DATE_ADD( '2009-01-01', interval @num := @num+1 day) AS date_sequence, 
    your_table.* FROM your_table
    WHERE your_table.other_column IS NOT NULL
    HAVING DATE_ADD('2009-01-01', interval @num day) <= '2009-01-13'
    

    @num равен -1, потому что вы добавляете к нему при первом использовании. Кроме того, вы не можете использовать «HAVING date_sequence», потому что при этом пользовательская переменная увеличивается вдвое для каждой строки.

    04.02.2009

    4

    У нас была аналогичная проблема с отчетами BIRT, поскольку мы хотели отчитываться в те дни, когда не было данных. Поскольку для этих дат не было записей, самым простым решением для нас было создать простую таблицу, в которой хранятся все даты, и использовать ее для получения диапазонов или объединения для получения нулевых значений для этой даты.

    У нас есть задание, которое выполняется каждый месяц, чтобы обеспечить заполнение таблицы на 5 лет вперед. Таблица создается таким образом:

    create table all_dates (
        dt date primary key
    );
    

    Несомненно, есть волшебные хитрые способы сделать это с помощью разных СУБД », но мы всегда выбираем самое простое решение. Требования к хранилищу для таблицы минимальны, что делает запросы намного проще и переносимыми. Такое решение почти всегда лучше с точки зрения производительности, поскольку не требует вычислений для каждой строки данных.

    Другой вариант (и мы использовали его раньше) - обеспечить наличие записи в таблице для каждой даты. Мы периодически просматривали таблицу и добавляли нулевые записи для дат и / или времени, которых не было. Это может быть не вариант в вашем случае, это зависит от сохраненных данных.

    Если вы действительно считаете, что поддерживать all_dates таблицу заполненной сложно, лучше всего использовать хранимую процедуру, которая вернет набор данных, содержащий эти даты. Это почти наверняка будет медленнее, поскольку вам придется вычислять диапазон каждый раз, когда он вызывается, а не просто извлекать предварительно рассчитанные данные из таблицы.

    Но, честно говоря, вы могли бы заполнить таблицу в течение 1000 лет без каких-либо серьезных проблем с хранением данных - 365000 16-байтовых (например) дат плюс индекс, дублирующий дату плюс 20% накладных расходов для безопасности, я бы приблизительно оценил в около 14M [365 000 * 16 * 2 * 1,2 = 14 016 000 байт]), крохотная таблица в схеме вещей.

    04.02.2009

    5

    Заимствование идеи из этот ответ, вы можете создать таблицу с цифрами от 0 до 9 и использовать ее для создания списка дат.

    CREATE TABLE num (i int);
    INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
    
    select adddate('2009-01-01', numlist.id) as `date` from
    (SELECT n1.i + n10.i*10 + n100.i*100 AS id
       FROM num n1 cross join num as n10 cross join num as n100) as numlist
    where adddate('2009-01-01', numlist.id) <= '2009-01-13';
    

    Это позволит вам создать список до 1000 дат. Если вам нужно сделать больше, вы можете добавить еще одно перекрестное соединение во внутренний запрос.

    04.02.2009
  • Это решение работает намного лучше. Но у него есть проблема с UNIX_TIMESTAMP () - он дает такие результаты, как 1231185600.000000; часть миллисекунд после десятичной точки; в то время как - ВЫБРАТЬ UNIX_TIMESTAMP (ADDDATE ('2009-01-01', 0)) AS date; НЕ приводит к этой части. 22.01.2015

  • 6

    Для доступа (или любого языка SQL)

    1. Создайте одну таблицу с 2 полями, мы назовем эту таблицу tempRunDates:
      --Fields fromDate и toDate
      - Затем вставьте только 1 запись, у которой есть дата начала и дата окончания.

    2. Создайте еще одну таблицу: Time_Day_Ref
      --Импортируйте список дат (создать список в Excel легко) в эту таблицу.
      - Имя поля в моем случае Greg_Dt, для григорианской даты
      - Я составлял свой список с 1 января 2009 года по 1 января 2020 года.

    3. Запустите запрос:

      SELECT Time_Day_Ref.GREG_DT
      FROM tempRunDates, Time_Day_Ref
      WHERE Time_Day_Ref.greg_dt>=tempRunDates.fromDate And greg_dt<=tempRunDates.toDate;
      

    Легкий!

    23.08.2011

    7

    Элегантное решение, использующее новую рекурсивную функциональность (общие табличные выражения) в MariaDB> = 10.3 и MySQL> = 8.0.

    WITH RECURSIVE t as (
        select '2019-01-01' as dt
      UNION
        SELECT DATE_ADD(t.dt, INTERVAL 1 DAY) FROM t WHERE DATE_ADD(t.dt, INTERVAL 1 DAY) <= '2019-04-30'
    )
    select * FROM t;
    

    Приведенное выше возвращает таблицу дат между «2019-01-01» и «2019-04-30».

    05.02.2019
  • выберите '2019-01-01' как dt, что это за селектор? Можно ли просто выбрать поле от и до? 29.07.2019

  • 8

    Обычно для этой цели можно использовать вспомогательную таблицу чисел с некоторыми вариациями:

    SELECT *
    FROM (
        SELECT DATEADD(d, number - 1, '2009-01-01') AS dt
        FROM Numbers
        WHERE number BETWEEN 1 AND DATEDIFF(d, '2009-01-01', '2009-01-13') + 1
    ) AS DateRange
    LEFT JOIN YourStuff
        ON DateRange.dt = YourStuff.DateColumn
    

    Я видел варианты с табличными функциями и т. Д.

    Вы также можете вести постоянный список свиданий. У нас есть это в нашем хранилище данных, а также список времени суток.

    04.02.2009

    9

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

    SELECT CAST(DAYNAME(daydate) as CHAR) as dayname,daydate
        FROM
        (select CAST((date_add('20110101', interval H.i*100 + T.i*10 + U.i day) )as DATE) as daydate
          from erp_integers as H
        cross
          join erp_integers as T
        cross
          join erp_integers as U
         where date_add('20110101', interval H.i*100 + T.i*10 + U.i day ) <= '20110228'
        order
            by daydate ASC
            )Days
    
    08.06.2011

    10

    Это решение работает с MySQL 5.0.
    Создайте таблицу - mytable.
    Схема не имеет значения. Важно количество строк в нем.
    Итак, вы можете сохранить только один столбец типа INT с 10 строками, значениями от 1 до 10.

    SQL:

    set @tempDate=date('2011-07-01') - interval 1 day;
    select
    date(@tempDate := (date(@tempDate) + interval 1 day)) as theDate
    from mytable x,mytable y
    group by theDate
    having theDate <= '2011-07-31';
    

    Ограничение: максимальное количество дат, возвращаемых вышеуказанным запросом, будет
    (rows in mytable)*(rows in mytable) = 10*10 = 100.

    Вы можете увеличить этот диапазон, изменив часть формы в sql:
    с mytable x, mytable y, mytable z
    Итак, диапазон будет 10*10*10 =1000 и так далее.

    04.08.2011

    11

    Вы можете использовать это

    SELECT CAST(cal.date_list AS DATE) day_year
    FROM (
      SELECT SUBDATE('2019-01-01', INTERVAL 1 YEAR) + INTERVAL xc DAY AS date_list
      FROM (
            SELECT @xi:=@xi+1 as xc from
            (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc1,
            (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc2,
            (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc3,
            (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc4,
            (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc5,
            (SELECT @xi:=-1) xc0
        ) xxc1
    ) cal
    WHERE cal.date_list BETWEEN '2019-01-01' AND '2019-12-31'
    ORDER BY cal.date_list DESC;
    
    05.08.2020

    12

    Создайте хранимую процедуру, которая принимает два параметра a_begin и a_end. Создайте внутри нее временную таблицу с именем t, объявите переменную d, назначьте a_begin переменной d и запустите цикл WHILE INSERTing d в t и вызовите функцию ADDDATE для увеличения значения d. Наконец SELECT * FROM t.

    04.02.2009
  • На самом деле я считаю, что постоянная таблица была бы лучше для скорости выполнения (имеет минимальные требования к хранилищу). Гораздо быстрее предварительно вычислить даты в таблице и извлечь их при необходимости, чем создавать диапазоны каждый раз, когда они вам нужны. 04.02.2009
  • @Pax, это зависит от того, стоит ли улучшение достигнутой скорости обслуживания таблицы. Например, если создание отчета занимает 3 секунды, а выполнение цикла WHILE для генерации дат занимает 0,001 секунды, я бы сказал, что прирост производительности игнорируется. Кнут: Преждевременная оптимизация - корень всех зол. 04.02.2009
  • @ eed3si9n, преждевременная оптимизация, да, не вся оптимизация :-) Если бы ваш пример был правильным, то да, я бы с вами согласился, но его следует измерять для уверенности. Table maint исчезнет, ​​если вы создадите его через 1000 лет (единовременная стоимость), как я предлагал, но эти секунды будут складываться. 04.02.2009

  • 13

    Я бы использовал что-то похожее на это:

    DECLARE @DATEFROM AS DATETIME
    DECLARE @DATETO AS DATETIME
    DECLARE @HOLDER TABLE(DATE DATETIME)
    
    SET @DATEFROM = '2010-08-10'
    SET @DATETO = '2010-09-11'
    
    INSERT INTO
        @HOLDER
            (DATE)
    VALUES
        (@DATEFROM)
    
    WHILE @DATEFROM < @DATETO
    BEGIN
    
        SELECT @DATEFROM = DATEADD(D, 1, @DATEFROM)
        INSERT 
        INTO
            @HOLDER
                (DATE)
        VALUES
            (@DATEFROM)
    END
    
    SELECT 
        DATE
    FROM
        @HOLDER
    

    Затем таблица @HOLDER Variable содержит все даты, увеличенные по дням между этими двумя датами, готовые к объединению, когда вам угодно.

    19.08.2010
  • Здравствуйте, я пытаюсь использовать код и вставить результат в таблицу, которую я определил DateTest с столбцом datefill типа DATETIME ... но не удалось ... не могли бы вы предоставить код, который будет работать с этим, пожалуйста? Примечание: здесь используется SQL Server. Спасибо :) 29.10.2011

  • 14

    Я уже давно борюсь с этим. Поскольку это первое попадание в Google, когда я искал решение, позвольте мне опубликовать, где я до сих пор добрался.

    SET @d := '2011-09-01';
    SELECT @d AS d, cast( @d := DATE_ADD( @d , INTERVAL 1 DAY ) AS DATE ) AS new_d
      FROM [yourTable]
      WHERE @d <= '2012-05-01';
    

    Замените [yourTable] таблицей из вашей базы данных. Хитрость заключается в том, что количество строк в выбранной вами таблице должно быть> = количеству дат, которые вы хотите вернуть. Я попытался использовать заполнитель таблицы DUAL, но он вернул только одну строку.

    06.04.2012
  • Интересный подход. Но .. разве это не то, что Виханг предложил выше;)? 07.04.2012

  • 15
    select * from table_name where col_Date between '2011/02/25' AND DATEADD(s,-1,DATEADD(d,1,'2011/02/27'))
    

    Здесь сначала добавьте день к текущей endDate, это будет 2011-02-28 00:00:00, затем вы вычтите одну секунду, чтобы получить конечную дату 2011-02-27 23:59:59. Таким образом вы можете получить все даты между заданными интервалами.

    вывод:
    2011/02/25
    2011/02/26
    2011/02/27

    15.08.2013

    16
    DELIMITER $$  
    CREATE PROCEDURE popula_calendario_controle()
       BEGIN
          DECLARE a INT Default 0;
          DECLARE first_day_of_year DATE;
          set first_day_of_year = CONCAT(DATE_FORMAT(curdate(),'%Y'),'-01-01');
          one_by_one: LOOP
             IF dayofweek(adddate(first_day_of_year,a)) <> 1 THEN
                INSERT INTO calendario.controle VALUES(null,150,adddate(first_day_of_year,a),adddate(first_day_of_year,a),1);
             END IF;
             SET a=a+1;
             IF a=365 THEN
                LEAVE one_by_one;
             END IF;
          END LOOP one_by_one;
    END $$
    

    эта процедура вставит все даты с начала года до настоящего момента, просто замените дни «начало» и «конец», и вы готовы к работе!

    10.07.2014
  • Как на линию IF a=365 THEN влияют високосные годы? 06.09.2016
  • Кроме того, каково значение числа 150 в строке 9? Этот код является стандартным ответом без особых пояснений. 06.09.2016

  • 17

    Мне нужен был список всех месяцев между двумя датами для статистики. Две даты - это дата начала и окончания подписки. Итак, в списке показаны все месяцы и количество подписок в месяц.

    MYSQL

    CREATE PROCEDURE `get_amount_subscription_per_month`()
    BEGIN
       -- Select the ultimate start and enddate from subscribers
       select @startdate := min(DATE_FORMAT(a.startdate, "%Y-%m-01")), 
              @enddate := max(DATE_FORMAT(a.enddate, "%Y-%m-01")) + interval 1 MONTH
       from subscription a;
    
       -- Tmp table with all months (dates), you can always format them with DATE_FORMAT) 
       DROP TABLE IF EXISTS tmp_months;
       create temporary table tmp_months (
          year_month date,
          PRIMARY KEY (year_month)
       );
    
    
       set @tempDate=@startdate;  #- interval 1 MONTH;
    
       -- Insert every month in tmp table
       WHILE @tempDate <= @enddate DO
         insert into tmp_months (year_month) values (@tempDate);
         set @tempDate = (date(@tempDate) + interval 1 MONTH);
       END WHILE;
    
       -- All months
       select year_month from tmp_months;
    
       -- If you want the amount of subscription per month else leave it out
       select mnd.year_month, sum(subscription.amount) as subscription_amount
       from tmp_months mnd
       LEFT JOIN subscription ON mnd.year_month >= DATE_FORMAT(subscription.startdate, "%Y-%m-01") and mnd.year_month <= DATE_FORMAT(subscription.enddate, "%Y-%m-01")
       GROUP BY mnd.year_month;
    
     END
    
    31.08.2016

    18

    Нет функции, нет процедур

    SET @s := '2020-01-01';
    SET @e := @s + INTERVAL 1 YEAR - INTERVAL 1 DAY; -- set end date to select
    
    SELECT CAST((DATE(@s)+INTERVAL (H+T+U) DAY) AS DATE) d -- generate a list of 400 days starting from @s date so @e can not be more then @s + 
    FROM ( SELECT 0 H
        UNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300
      ) H CROSS JOIN ( SELECT 0 T
        UNION ALL SELECT  10 UNION ALL SELECT  20 UNION ALL SELECT  30
        UNION ALL SELECT  40 UNION ALL SELECT  50 UNION ALL SELECT  60
        UNION ALL SELECT  70 UNION ALL SELECT  80 UNION ALL SELECT  90
      ) T CROSS JOIN ( SELECT 0 U
        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
      ) U
     -- generated lenght of date list can be calculated as fallow 1 * H(3 + 1) * T(9 + 1) * U(9 + 1) = 400
     -- it is crucial to preserve the numbering convention as 1, 2 ... 20, 30..., 100, 200, ... to retrieve chronological date selection
     -- add more UNION 400, 500, 600, ... H(6 + 1) if you want to select from more than 700 days!
    WHERE
      (DATE(@s+INTERVAL (H+T+U) DAY)) <= DATE((@e))
    ORDER BY d;
    

    СОЮЗЫ определяют длину и диапазон доступных дат для выбора. Так что всегда следите за тем, чтобы журнал был достаточным.

    SELECT 1 * (3 + 1) * (9 + 1) * (9 + 1); -- 400 days starting from from @s
    

    На основе этой статьи < br> Протестировано и работает должным образом

    17.07.2021

    19

    Без временной таблицы, без процедуры, без функций

    SET @s := '2021-12-01'; -- start at
    SET @e := @s + INTERVAL 1 MONTH - INTERVAL 1 DAY; -- 2021-12-31
    
    WITH recursive d_range AS (
        select @s as Date
       union all
       select Date + interval 1 day
       from d_range
       where Date < @e)
    select * from d_range;
    

    Результат:

    | Date       |
    +------------+
    | 2021-12-01 |
    | 2021-12-02 |
    | 2021-12-03 |
    | 2021-12-04 |
    | 2021-12-05 |
    | 2021-12-06 |
    | 2021-12-07 |
    | 2021-12-08 |
    | 2021-12-09 |
    | 2021-12-10 |
    | 2021-12-11 |
    | 2021-12-12 |
    | 2021-12-13 |
    | 2021-12-14 |
    | 2021-12-15 |
    | 2021-12-16 |
    | 2021-12-17 |
    | 2021-12-18 |
    | 2021-12-19 |
    | 2021-12-20 |
    | 2021-12-21 |
    | 2021-12-22 |
    | 2021-12-23 |
    | 2021-12-24 |
    | 2021-12-25 |
    | 2021-12-26 |
    | 2021-12-27 |
    | 2021-12-28 |
    | 2021-12-29 |
    | 2021-12-30 |
    | 2021-12-31 |
    +------------+
    -> 31 rows in set (0.037 sec)
    

    Примечание. этот запрос выполняется довольно медленно. А при выборе более длинных диапазонов дат он станет еще медленнее.

    17.07.2021

    20

    Я использую Server version: 5.7.11-log MySQL Community Server (GPL)

    Теперь решим это простым способом.

    Я создал таблицу с названием "datetable"

    mysql> describe datetable;
    +---------+---------+------+-----+---------+-------+
    | Field   | Type    | Null | Key | Default | Extra |
    +---------+---------+------+-----+---------+-------+
    | colid   | int(11) | NO   | PRI | NULL    |       |
    | coldate | date    | YES  |     | NULL    |       |
    +---------+---------+------+-----+---------+-------+
    2 rows in set (0.00 sec)
    

    теперь мы увидим вставленные записи внутри.

    mysql> select * from datetable;
    +-------+------------+
    | colid | coldate    |
    +-------+------------+
    |   101 | 2015-01-01 |
    |   102 | 2015-05-01 |
    |   103 | 2016-01-01 |
    +-------+------------+
    3 rows in set (0.00 sec)
    

    и здесь наш запрос на выборку записей за две даты, а не за эти даты.

    mysql> select * from datetable where coldate > '2015-01-01' and coldate < '2016-01-01';
    +-------+------------+
    | colid | coldate    |
    +-------+------------+
    |   102 | 2015-05-01 |
    +-------+------------+
    1 row in set (0.00 sec)
    

    надеюсь, что это поможет многим.

    19.04.2018
  • Проголосовали против без какой-либо причины, этот SQL в порядке и в рабочем сценарии. 29.07.2019
  • Это не отвечает на вопрос 28.02.2021
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..