Mysql 在加入后用DB中的以下日期的值填充
我实际上需要用归档中的下一个可用数据填充不存在的条目 背景:所以我有一个记录,它每个月都会存档每个状态。但是,它仅在有新值时更新,并将旧值保存到上个月。使用MySQL v8 如何使用下一个填写时间段中具有相同ID的数据填写表中缺少的值? 带有Mysql 在加入后用DB中的以下日期的值填充,mysql,sql,join,Mysql,Sql,Join,我实际上需要用归档中的下一个可用数据填充不存在的条目 背景:所以我有一个记录,它每个月都会存档每个状态。但是,它仅在有新值时更新,并将旧值保存到上个月。使用MySQL v8 如何使用下一个填写时间段中具有相同ID的数据填写表中缺少的值? 带有archivesDate='2019-08-01'的所有内容中故意包含空数据。这意味着下个月是数据开始的时候 中间3个带有archivesDate='2019-09-01'的数据需要在以后填写下一个具有相同状态ID的数据;在这种情况下,它来自archives
archivesDate='2019-08-01'
的所有内容中故意包含空数据。这意味着下个月是数据开始的时候
中间3个带有archivesDate='2019-09-01'
的数据需要在以后填写下一个具有相同状态ID的数据;在这种情况下,它来自archivesDate='2019-10-01'
。这可能是10月或11月,也可能是未来的任何时候。它只需要填写下一个值
我尝试过的,但它只是ID上的一个连接,这就是为什么九月显示为NULL
SELECT
al.statusID,
sa.statusDate,
sa.statusFlagsID,
sa.statusPrice,
al.archivesDate
FROM (
SELECT
sid.statusID AS statusID,
a.archivesID AS archivesID,
a.archivesDate AS archivesDate
FROM (
SELECT
DISTINCT statusID
FROM statusArchive) sid
CROSS JOIN archives a) al
LEFT JOIN statusArchive sa
ON sa.statusID = al.statusID --This needs to be changed to get next value in cases where there is no value available
AND sa.archivesID = al.archivesID --This needs to be changed to get next value in cases where there is no value available
ORDER BY al.archivesDate, al.statusID
电流输出:
statusID statusDate statusFlagsID statusPrice archivesDate
1 2019-08-01
2 2019-08-01
3 2019-08-01
1 2019-09-01
2 2019-09-01
3 2019-09-01
1 2018-10-01 1 37 2019-10-01
2 2018-11-05 1 90 2019-10-01
3 2019-01-01 1 3 2019-10-01
statusID statusDate statusFlagsID statusPrice archivesDate
1 2019-08-01
2 2019-08-01
3 2019-08-01
1 2018-10-01 1 37 2019-09-01
2 2018-11-05 1 90 2019-09-01
3 2019-01-01 1 3 2019-09-01
1 2018-10-01 1 37 2019-10-01
2 2018-11-05 1 90 2019-10-01
3 2019-01-01 1 3 2019-10-01
所需输出:
statusID statusDate statusFlagsID statusPrice archivesDate
1 2019-08-01
2 2019-08-01
3 2019-08-01
1 2019-09-01
2 2019-09-01
3 2019-09-01
1 2018-10-01 1 37 2019-10-01
2 2018-11-05 1 90 2019-10-01
3 2019-01-01 1 3 2019-10-01
statusID statusDate statusFlagsID statusPrice archivesDate
1 2019-08-01
2 2019-08-01
3 2019-08-01
1 2018-10-01 1 37 2019-09-01
2 2018-11-05 1 90 2019-09-01
3 2019-01-01 1 3 2019-09-01
1 2018-10-01 1 37 2019-10-01
2 2018-11-05 1 90 2019-10-01
3 2019-01-01 1 3 2019-10-01
编辑:添加了实体模型源表(包含提供上述信息的所有信息):
源数据
档案
archivesID archivesDate
1 2019-08-01
2 2019-09-01
3 2019-10-01
STATUSARCHIVE(将s替换为以下列名中的状态,因此格式问题很抱歉)
注意:archivesID=2
sArchiveID sID sFlagsID sPrice sDate archivesID
1 1 NULL NULL NULL 1
2 2 NULL NULL NULL 1
3 3 NULL NULL NULL 1
4 1 1 37 2018-10-01 3
5 2 1 90 2018-11-05 3
6 3 1 3 2019-01-01 3
和DB Fiddle以及创建数据源的SQL:
CREATE TEMPORARY TABLE archives (
archivesID INT,
archivesDate DATE
);
INSERT INTO archives (archivesID, archivesDate) VALUES (1, '2019-08-01');
INSERT INTO archives (archivesID, archivesDate) VALUES (2, '2019-09-01');
INSERT INTO archives (archivesID, archivesDate) VALUES (3, '2019-10-01');
CREATE TEMPORARY TABLE statusArchive (
statusArchiveID INT,
statusID INT,
statusFlagsID INT,
statusPrice DECIMAL,
statusDate DATE,
archivesID INT
);
INSERT INTO statusArchive (statusArchiveID, statusID, statusFlagsID, statusPrice, statusDate, archivesID)
VALUES (1, 1, NULL, NULL, NULL, 1);
INSERT INTO statusArchive (statusArchiveID, statusID, statusFlagsID, statusPrice, statusDate, archivesID)
VALUES (2, 2, NULL, NULL, NULL, 1);
INSERT INTO statusArchive (statusArchiveID, statusID, statusFlagsID, statusPrice, statusDate, archivesID)
VALUES (3, 3, NULL, NULL, NULL, 1);
INSERT INTO statusArchive (statusArchiveID, statusID, statusFlagsID, statusPrice, statusDate, archivesID)
VALUES (4, 1, 1, 37, '2018-10-01', 3);
INSERT INTO statusArchive (statusArchiveID, statusID, statusFlagsID, statusPrice, statusDate, archivesID)
VALUES (5, 2, 1, 90, '2018-11-05', 3);
INSERT INTO statusArchive (statusArchiveID, statusID, statusFlagsID, statusPrice, statusDate, archivesID)
VALUES (6, 3, 1, 3, '2019-01-01', 3);
快速修复:将您的评论翻译成代码
AND sa.archivesID = al.archivesID -- This needs to be changed to get next value
-- in cases where there is no value available
变成
AND sa.archivesID = (
SELECT MIN(x.archivesID)
FROM statusArchive x
WHERE x.statusID = al.statusID
AND x.archivesID >= al.archivesID
)
完整查询:
SELECT
al.statusID,
sa.statusDate,
sa.statusFlagsID,
sa.statusPrice,
al.archivesDate
FROM (
SELECT
sid.statusID AS statusID,
a.archivesID AS archivesID,
a.archivesDate AS archivesDate
FROM (SELECT DISTINCT statusID FROM statusArchive) sid
CROSS JOIN archives a
) al
LEFT JOIN statusArchive sa
ON sa.statusID = al.statusID
AND sa.archivesID = (
SELECT MIN(x.archivesID)
FROM statusArchive x
WHERE x.statusID = al.statusID
AND x.archivesID >= al.archivesID
)
ORDER BY al.archivesDate, al.statusID
结果:
| statusID | archivesDate | statusDate | statusFlagsID | statusPrice |
| -------- | ------------ | ---------- | ------------- | ----------- |
| 1 | 2019-08-01 | | | |
| 2 | 2019-08-01 | | | |
| 3 | 2019-08-01 | | | |
| 1 | 2019-09-01 | 2018-10-01 | 1 | 37 |
| 2 | 2019-09-01 | 2018-11-05 | 1 | 90 |
| 3 | 2019-09-01 | 2019-01-01 | 1 | 3 |
| 1 | 2019-10-01 | 2018-10-01 | 1 | 37 |
| 2 | 2019-10-01 | 2018-11-05 | 1 | 90 |
| 3 | 2019-10-01 | 2019-01-01 | 1 | 3 |
| statusID | statusDate | statusFlagsID | statusPrice | archivesDate |
| -------- | ---------- | ------------- | ----------- | ------------ |
| 1 | | | | 2019-08-01 |
| 2 | | | | 2019-08-01 |
| 3 | | | | 2019-08-01 |
| 1 | 2018-10-01 | 1 | 37 | 2019-09-01 |
| 2 | 2018-11-05 | 1 | 90 | 2019-09-01 |
| 3 | 2019-01-01 | 1 | 3 | 2019-09-01 |
| 1 | 2018-10-01 | 1 | 37 | 2019-10-01 |
| 2 | 2018-11-05 | 1 | 90 | 2019-10-01 |
| 3 | 2019-01-01 | 1 | 3 | 2019-10-01 |
注意:您应该在statusArchive(statusID,archivesID[其他列])上有一个索引。
以下(较短)查询也适用于给定的示例数据:
select
s.statusID,
s.statusDate,
s.statusFlagsID,
s.statusPrice,
a.archivesDate
from archives a
left join statusArchive s
on s.archivesID = (
select min(x.archivesID)
from statusArchive x
where x.archivesID >= a.archivesID
)
order by a.archivesDate, s.statusID;
对于此查询,您应该在statusArchive(archivesID)
上有一个索引
结果:
| statusID | archivesDate | statusDate | statusFlagsID | statusPrice |
| -------- | ------------ | ---------- | ------------- | ----------- |
| 1 | 2019-08-01 | | | |
| 2 | 2019-08-01 | | | |
| 3 | 2019-08-01 | | | |
| 1 | 2019-09-01 | 2018-10-01 | 1 | 37 |
| 2 | 2019-09-01 | 2018-11-05 | 1 | 90 |
| 3 | 2019-09-01 | 2019-01-01 | 1 | 3 |
| 1 | 2019-10-01 | 2018-10-01 | 1 | 37 |
| 2 | 2019-10-01 | 2018-11-05 | 1 | 90 |
| 3 | 2019-10-01 | 2019-01-01 | 1 | 3 |
| statusID | statusDate | statusFlagsID | statusPrice | archivesDate |
| -------- | ---------- | ------------- | ----------- | ------------ |
| 1 | | | | 2019-08-01 |
| 2 | | | | 2019-08-01 |
| 3 | | | | 2019-08-01 |
| 1 | 2018-10-01 | 1 | 37 | 2019-09-01 |
| 2 | 2018-11-05 | 1 | 90 | 2019-09-01 |
| 3 | 2019-01-01 | 1 | 3 | 2019-09-01 |
| 1 | 2018-10-01 | 1 | 37 | 2019-10-01 |
| 2 | 2018-11-05 | 1 | 90 | 2019-10-01 |
| 3 | 2019-01-01 | 1 | 3 | 2019-10-01 |
然而,我不知道这是否会在任何可能的数据集上返回所需的结果,因为我只能从您的样本数据和结果中猜测确切的要求
更新
如果需要根据相应的归档日期对下一行进行排序,则需要一个排序依据。。。限制1
子查询:
SELECT
al.statusID,
sa.statusDate,
sa.statusFlagsID,
sa.statusPrice,
al.archivesDate
FROM (
SELECT
sid.statusID AS statusID,
a.archivesID AS archivesID,
a.archivesDate AS archivesDate
FROM (SELECT DISTINCT statusID FROM statusArchive) sid
CROSS JOIN archives a
) al
LEFT JOIN statusArchive sa
ON sa.statusID = al.statusID
AND sa.archivesID = (
SELECT x.archivesID
FROM statusArchive x
JOIN archives y ON y.archivesID = x.archivesID
WHERE x.statusID = al.statusID
AND y.archivesDate >= al.archivesDate
ORDER BY y.archivesDate ASC
LIMIT 1
)
ORDER BY al.archivesDate, al.statusID;
让舒尔成为你的首选
statusArchive(statusID[,其他列])
对于x.statusID=al.statusID
以及对于从statusArchive中选择不同的statusID
存档(archivesID,archivesDate,[,其他列])
用于条件y.archivesID=x.archivesID
和y.archivesDate>=al.archivesDate
以及ORDER BY子句y.archivesDate ASC
输出是什么样子的?@TimBiegeleisen添加了更好的格式以澄清示例数据,而db FIDLE将非常有用。我不知道这些值是从哪里来的。@现在怎么样?刚刚测试过,如果我将其中一个存档ID更改为4,也可以工作,这也指向一个更晚的日期。干得好,谢谢!我如何在最小存档日期加入此项?在statusArchive
中没有archivesDate
。您的意思是最小statusDate
?根据问题,如果ID不符合顺序,它需要按日期。有一个archivesID,它连接到存档表以获取日期…因此,通过archivesDate(archivesID所指),我添加了一个编辑,希望它得到批准。