Как заполнить пропущенную дату в таблице sql - PullRequest
1 голос
/ 04 апреля 2020

У меня есть таблица sql, относящаяся к периодическим датам: enter image description here

CREATE TABLE IF NOT EXISTS date_test1 ( items CHAR ( 8 ), trade_date date );
INSERT INTO `date_test1` VALUES ( 'a', '2020-03-20');
INSERT INTO `date_test1` VALUES ( 'b',  '2020-03-20');
INSERT INTO `date_test1` VALUES ('a', '2020-03-21');
INSERT INTO `date_test1` VALUES ( 'c', '2020-03-22');
INSERT INTO `date_test1` VALUES ( 'd',  '2020-03-22');
INSERT INTO `date_test1` VALUES ('a',  '2020-03-25');
INSERT INTO `date_test1` VALUES ( 'e',  '2020-03-26');

В этой таблице '2020-03-23' и '2020-03- 24 'пропущены. Я хочу заполнить их их предыдущими данными, в этой таблице данные «2020-03-22». Ожидаемый результат: enter image description here

Число продолжающихся пропущенных дат и записей за один день являются неопределенными. Так как это сделать в mysql?

1 Ответ

0 голосов
/ 04 апреля 2020

В этом решении используется Python и предполагается, что строк не так много, чтобы их нельзя было прочитать в память. Я не гарантирую, что этот код свободен от дефектов; использовать на свой страх и риск . Поэтому я предлагаю вам выполнить это для копии вашей таблицы или сначала создать резервную копию.

В этом коде используется драйвер pymysql.

import pymysql
from datetime import date, timedelta
from itertools import groupby
import sys

conn = pymysql.connect(db='x', user='x', password='x', charset='utf8mb4', use_unicode=True)
cursor = conn.cursor()
# must be sorted by date:
cursor.execute('select items, trade_date from date_test1 order by trade_date, items')
rows = cursor.fetchall() # tuples: (datetime.date, str)
if len(rows) == 0:
    sys.exit(0)
groups = []
for k, g in groupby(rows, key=lambda row: row[1]):
    groups.append(list(g))
one_day = timedelta(days=1)
previous_group = groups.pop(0)
next_date = previous_group[0][1]
for group in groups:
    next_date = next_date + one_day
    while group[0][1] != next_date:
        # missing date
        for tuple in previous_group:
            cursor.execute('insert into date_test1(items, trade_date) values(%s, %s)', (tuple[0], next_date))
            print('inserting', tuple[0], next_date)
        conn.commit()
        next_date = next_date + one_day
    previous_group = group

Отпечатки:

inserting c 2020-03-23
inserting d 2020-03-23
inserting c 2020-03-24
inserting d 2020-03-24

Обсуждение

С вашими примерами данных, после выборки строк, rows будет:

(('a', datetime.date(2020, 3, 20)), ('b', datetime.date(2020, 3, 20)), ('a', datetime.date(2020, 3, 21)), ('c', datetime.date(2020, 3, 22)), ('d', datetime.date(2020, 3, 22)), ('a', datetime.date(2020, 3, 25)), ('e', datetime.date(2020, 3, 26)))

После выполнения следующего:

groups = []
for k, g in groupby(rows, key=lambda row: row[1]):
    groups.append(list(g))

groups - это:

[[('a', datetime.date(2020, 3, 20)), ('b', datetime.date(2020, 3, 20))], [('a', datetime.date(2020, 3, 21))], [('c', datetime.date(2020, 3, 22)), ('d', datetime.date(2020, 3, 22))], [('a', datetime.date(2020, 3, 25))], [('e', datetime.date(2020, 3, 26))]]

То есть все кортежи с одной и той же датой сгруппированы в списке, что упрощает обнаружение пропущенных дат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...