если ваш mysql поддерживает cte recursive
, вы можете попробовать использовать его для создания таблицы календаря.
Затем выполните outer join
и выполните подзапрос с case when
Схема (MySQL v8.0)
CREATE TABLE T(
ID int,
Name varchar(50),
SomeVal float,
OtherVal float,
`Date` date
);
insert into T values (10,'Somebody',33001.93,33001.93,'2018-10-01');
insert into T values (10,'Somebody',33481.93,33481.93,'2018-10-02');
insert into T values (10,'Somebody',33001.93,33001.93,'2018-10-03');
insert into T values (10,'Somebody',33582.76,33582.76,'2018-10-04');
insert into T values (10,'Somebody',33582.73,33582.79,'2018-10-05');
insert into T values (10,'Somebody',33582.76,33582.76,'2018-10-08');
insert into T values (10,'Somebody',33462.76,33462.76,'2018-10-10');
Запрос № 1
WITH recursive CTE as(
SELECT MIN(Date) minDt,MAX(Date) maxDt
FROM T
UNION ALL
SELECT date_add(minDt,INTERVAL 1 DAY),maxDt
FROM CTE
WHERE minDt < maxDt
)
SELECT
CASE WHEN ID IS NULL THEN (SELECT ID
FROM T tt
WHERE tt.Date < t1.minDt
ORDER BY tt.Date DESC
LIMIT 1)
ELSE ID END ID,
CASE WHEN Name IS NULL THEN (SELECT Name
FROM T tt
WHERE tt.Date < t1.minDt
ORDER BY tt.Date DESC
LIMIT 1)
ELSE Name END Name,
CASE WHEN SomeVal IS NULL THEN (SELECT SomeVal
FROM T tt
WHERE tt.Date < t1.minDt
ORDER BY tt.Date DESC
LIMIT 1)
ELSE SomeVal END SomeVal,
CASE WHEN OtherVal IS NULL THEN (SELECT OtherVal
FROM T tt
WHERE tt.Date < t1.minDt
ORDER BY tt.Date DESC
LIMIT 1)
ELSE OtherVal END OtherVal,
minDt
FROM CTE t1
LEFT JOIN T t2 ON t1.minDt = t2.Date
ORDER BY t1.minDT;
| ID | Name | SomeVal | OtherVal | minDt |
| --- | -------- | -------------- | -------------- | ---------- |
| 10 | Somebody | 33001.9296875 | 33001.9296875 | 2018-10-01 |
| 10 | Somebody | 33481.9296875 | 33481.9296875 | 2018-10-02 |
| 10 | Somebody | 33001.9296875 | 33001.9296875 | 2018-10-03 |
| 10 | Somebody | 33582.76171875 | 33582.76171875 | 2018-10-04 |
| 10 | Somebody | 33582.73046875 | 33582.7890625 | 2018-10-05 |
| 10 | Somebody | 33582.73046875 | 33582.7890625 | 2018-10-06 |
| 10 | Somebody | 33582.73046875 | 33582.7890625 | 2018-10-07 |
| 10 | Somebody | 33582.76171875 | 33582.76171875 | 2018-10-08 |
| 10 | Somebody | 33582.76171875 | 33582.76171875 | 2018-10-09 |
| 10 | Somebody | 33462.76171875 | 33462.76171875 | 2018-10-10 |
Просмотр на БД Fiddle
Если ваша версия mysql не поддерживает cte
, вы можете создать таблицу календаря для outer join
Схема (MySQL v5.7)
CREATE TABLE T(
ID int,
Name varchar(50),
SomeVal float,
OtherVal float,
`Date` date
);
insert into T values (10,'Somebody',33001.93,33001.93,'2018-10-01');
insert into T values (10,'Somebody',33481.93,33481.93,'2018-10-02');
insert into T values (10,'Somebody',33001.93,33001.93,'2018-10-03');
insert into T values (10,'Somebody',33582.76,33582.76,'2018-10-04');
insert into T values (10,'Somebody',33582.73,33582.79,'2018-10-05');
insert into T values (10,'Somebody',33582.76,33582.76,'2018-10-08');
insert into T values (10,'Somebody',33462.76,33462.76,'2018-10-10');
CREATE Table calendar(
minDt Date
);
INSERT INTO calendar values ('2018-10-01');
INSERT INTO calendar values ('2018-10-02');
INSERT INTO calendar values ('2018-10-03');
INSERT INTO calendar values ('2018-10-04');
INSERT INTO calendar values ('2018-10-05');
INSERT INTO calendar values ('2018-10-06');
INSERT INTO calendar values ('2018-10-07');
INSERT INTO calendar values ('2018-10-08');
INSERT INTO calendar values ('2018-10-09');
INSERT INTO calendar values ('2018-10-10');
Запрос № 1
SELECT
CASE WHEN ID IS NULL THEN (SELECT ID
FROM T tt
WHERE tt.Date < t1.minDt
ORDER BY tt.Date DESC
LIMIT 1)
ELSE ID END ID,
CASE WHEN Name IS NULL THEN (SELECT Name
FROM T tt
WHERE tt.Date < t1.minDt
ORDER BY tt.Date DESC
LIMIT 1)
ELSE Name END Name,
CASE WHEN SomeVal IS NULL THEN (SELECT SomeVal
FROM T tt
WHERE tt.Date < t1.minDt
ORDER BY tt.Date DESC
LIMIT 1)
ELSE SomeVal END SomeVal,
CASE WHEN OtherVal IS NULL THEN (SELECT OtherVal
FROM T tt
WHERE tt.Date < t1.minDt
ORDER BY tt.Date DESC
LIMIT 1)
ELSE OtherVal END OtherVal,
minDt
FROM calendar t1
LEFT JOIN T t2 ON t1.minDt = t2.Date
ORDER BY t1.minDT;
| ID | Name | SomeVal | OtherVal | minDt |
| --- | -------- | -------------- | -------------- | ---------- |
| 10 | Somebody | 33001.9296875 | 33001.9296875 | 2018-10-01 |
| 10 | Somebody | 33481.9296875 | 33481.9296875 | 2018-10-02 |
| 10 | Somebody | 33001.9296875 | 33001.9296875 | 2018-10-03 |
| 10 | Somebody | 33582.76171875 | 33582.76171875 | 2018-10-04 |
| 10 | Somebody | 33582.73046875 | 33582.7890625 | 2018-10-05 |
| 10 | Somebody | 33582.73046875 | 33582.7890625 | 2018-10-06 |
| 10 | Somebody | 33582.73046875 | 33582.7890625 | 2018-10-07 |
| 10 | Somebody | 33582.76171875 | 33582.76171875 | 2018-10-08 |
| 10 | Somebody | 33582.76171875 | 33582.76171875 | 2018-10-09 |
| 10 | Somebody | 33462.76171875 | 33462.76171875 | 2018-10-10 |
Посмотреть на БД Fiddle