防止在基于记录日期的查询中加入较旧的日期记录

Posted

技术标签:

【中文标题】防止在基于记录日期的查询中加入较旧的日期记录【英文标题】:Prevent joining of older date records in query based on date of records 【发布时间】:2017-12-03 04:48:16 【问题描述】:

这是SQL Fiddle,我用我在下面讨论的所有内容创建,但此查询将专门设置为仅查询同一天的记录,例如2017-11-29 所以这个例子就足够了。

我有两个数据表

    要运行的批次(表 1)

    这是要运行的批次数的 例如2 of 25 其中25 是从该表中获取的值 我不希望在此查询中看到任何小于1 值的记录 我也只想查看 3 字段的 3 值的记录

    批次计数(表2)

    这是运行的批号的 例如2 of 25 其中2 是从此表中获取的值 我不希望在此查询中看到零 0

当我在 BTR 表中只有一个特定日期的值时,我总是会得到预期的结果(即,1 of 252 of 25 总是如此)。

当一天中有多个“要运行的批次”记录集(根据示例数据)并且其值被重置为另一个有效值但同一天具有不同且更新的时间戳时,


问题

如何明智地防止加入比较新/当前/最新 BTR 记录时间戳更旧的 BC 记录,以防止无效结果 SQL Fiddle 我提供的示例在 2017-11-29T13:59:59Z 时间的记录处启动此问题戳 (TimeStr)?

我不希望 BC 表中的旧记录与 BTR 表中的下一个/较新/最新时间戳记录匹配,并希望它根据时间移动到下一个真实记录值,以便在存在较新的 BTR 记录时,在下一个新记录之前,不要看任何小于那个时间的东西。


原始 SQL

创建表格并插入数据

CREATE TABLE `batchestorun` (
  `TimeInt` varchar(10) NOT NULL,
  `TimeStr` datetime NOT NULL,
  `IsInitValue` int(11) NOT NULL,
  `Value` int(11) NOT NULL,
  `IQuality` int(11) NOT NULL,
  UNIQUE KEY `uk_Times` (`TimeInt`,`TimeStr`)
); 

CREATE TABLE `batchescomplete` (
  `TimeInt` varchar(10) NOT NULL,
  `TimeStr` datetime NOT NULL,
  `IsInitValue` int(11) NOT NULL,
  `Value` int(11) NOT NULL,
  `IQuality` int(11) NOT NULL,
  UNIQUE KEY `uk_Times` (`TimeInt`,`TimeStr`)
);

## BTR
INSERT INTO `batchestorun` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511917564','2017-11-29 01:06:04',1,0,0);
INSERT INTO `batchestorun` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511938976','2017-11-29 07:02:56',0,21,3);
INSERT INTO `batchestorun` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511962086','2017-11-29 13:28:06',0,0,3);
INSERT INTO `batchestorun` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511962089','2017-11-29 13:28:09',0,1,3);
INSERT INTO `batchestorun` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511962979','2017-11-29 13:42:59',0,20,3);
INSERT INTO `batchestorun` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511971912','2017-11-29 16:11:52',0,0,3);
INSERT INTO `batchestorun` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511971934','2017-11-29 16:12:14',0,25,3);

## BC
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511917564','2017-11-29 01:06:04',1,0,0);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511939767','2017-11-29 07:16:07',0,1,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511940230','2017-11-29 07:23:50',0,2,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511940692','2017-11-29 07:31:32',0,3,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511942121','2017-11-29 07:55:21',0,4,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511944099','2017-11-29 08:28:19',0,5,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511945511','2017-11-29 08:51:51',0,6,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511947447','2017-11-29 09:24:07',0,7,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511948408','2017-11-29 09:40:08',0,8,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511949620','2017-11-29 10:00:20',0,9,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511951571','2017-11-29 10:32:51',0,10,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511952520','2017-11-29 10:48:40',0,11,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511953011','2017-11-29 10:56:51',0,12,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511953960','2017-11-29 11:12:40',0,13,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511954905','2017-11-29 11:28:25',0,14,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511955860','2017-11-29 11:44:20',0,15,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511956351','2017-11-29 11:52:31',0,16,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511959198','2017-11-29 12:39:58',0,17,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511960194','2017-11-29 12:56:34',0,18,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511960731','2017-11-29 13:05:31',0,19,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511961677','2017-11-29 13:21:17',0,20,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511962086','2017-11-29 13:28:06',0,0,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511962849','2017-11-29 13:40:49',0,1,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511963999','2017-11-29 13:59:59',0,2,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511965321','2017-11-29 14:22:01',0,3,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511971912','2017-11-29 16:11:52',0,0,3);
INSERT INTO `batchescomplete` (`TimeInt`,`TimeStr`,`IsInitValue`,`Value`,`IQuality`) VALUES ('1511971935','2017-11-29 16:12:15',0,1,3);

加入查询

SELECT
     IF(btr.TimeStr<= bc.TimeStr, CONCAT(bc.Value," of ",btr.Value), '') Batch
    , bc.TimeStr
FROM BatchesComplete bc
    INNER JOIN BatchesToRun btr ON btr.TimeStr <= bc.TimeStr
    WHERE btr.Value >1 AND bc.Value >0 AND btr.IQuality = 3;

#SELECT * FROM batchestorun;
#SELECT * FROM batchescomplete;   
#SELECT * FROM batchestorun WHERE Value >1;
#SELECT * FROM batchescomplete WHERE Value >0;


预期结果示例

因此,根据SQL Fiddle 中的结果集,我提供了从第一行的1 of 21 到第20 行的20 of 21Batch 列记录都是正确的。

之后的行与20 的下一个BTRValue 字段何时起作用相关,结果显示2017-11-29 13:59:59 "BC" Value 字段与以前的“BTR”和新的“BTR”两者。


虽然同时获得2 of 202 of 21,但我需要它只显示2 of 20 以获得下一个/较新的“BTR”值,而不是回头看并加入任何旧记录最新“BTR”表Value记录的TimeStr

另一个预期结果示例

所以在我的示例中的前 20 条记录之后,我希望结果 看起来像这样 - 越近越好,但我什至可以掀起一些东西 如果你能帮我搞定一些事情。

表关系

【问题讨论】:

我在此查询中提到“”我指的是实际的Value 字段,以防有人想知道我想提一下,如果我的意思仅针对该领域进行记录。 这两个表(BC 和 BTR)是如何链接的?你能显示你用来加入它们的 SQL 接近你想要的吗? @ChrisCarr 这些表是按照我提供的sqlfiddle.com/#!9/e94b86/6 示例中的TimeStr 连接的。在这种情况下,没有键或类似的东西,并且关系是表到表,并且数据从这些表中链接到 TimeStr 列条件。 @ChrisCarr 此外,这个sqlfiddle.com/#!9/e94b86/31 可以帮助您查看 JOIN 条件中的所有数据(如果有帮助的话)。有人说要使用GROUP BY,然后删除了答案,所以我尝试了但看起来不对,当我回去检查时,答案被删除了。 【参考方案1】:

我想我明白你想要做什么。您需要进行子选择以从 BTR 检索 MAX(timestr) 并使用它来进行连接。我对查询进行了一些重新排列,但我认为这可能是您所追求的:

SELECT bc.value, btr.value, bc.timestr, btr.timestr 
FROM batchescomplete bc,
     batchestorun btr
WHERE btr.timestr = (SELECT MAX(btr2.timestr) FROM batchestorun btr2 WHERE bc.timestr >= btr2.TimeStr and btr2.value > 1 and btr2.IQuality = 3)
    AND bc.value > 0

【讨论】:

感谢您对如此简单的解决方案的帮助。我对查询进行了一些小调整以获得我的确切结果,但您似乎已经注意到子选择 WHERE 子句过滤方法!【参考方案2】:

我从您的“预期结果示例”视觉效果中假设您希望以以下方式显示行:

Green BTR Row
Green BC Rows
Red BTR Row
Red BC Rows
Blue BTR Row
Blue BC Row

为此,您实际上不需要加入表格。只需对每个表应用所需的过滤,用联合将两个结果集粉碎在一起,然后按 TimeStr 对行进行排序:

SELECT * FROM batchestorun WHERE Value >1
union all
SELECT * FROM batchescomplete WHERE Value >0
order by timestr

结果: http://sqlfiddle.com/#!9/e94b86/34

如果我误解了您想要的输出,请告诉我。

【讨论】:

以上是关于防止在基于记录日期的查询中加入较旧的日期记录的主要内容,如果未能解决你的问题,请参考以下文章

powershell 使用较旧的日期戳生成随机文件

如何提高大型表上基于日期的查询性能?

防止来自主机数据库的时区值被客户端覆盖

记录数正确显示,但当日期是相当旧的日期时,“新计算开始日期”列显示所有“######”格式,例如:01-DEC-1184

这足以防止 SQL 注入吗?

从基于日期的版本控制切换到语义版本控制后,如何防止 NuGet 升级包?