位于其他表中的值之间的计数的 SQL 查询

Posted

技术标签:

【中文标题】位于其他表中的值之间的计数的 SQL 查询【英文标题】:SQL Query of Counts That Lie Between Values in Other Table 【发布时间】:2021-12-19 20:38:02 【问题描述】:

我不确定如何表达标题。我有一个我想不通的问题:

我有一个带有时间戳(十进制 1970 纪元)的表“值”和每行的一个 blob。我有一个名为“keys”的第二个表,其中包含用于解密第一个表“values”中每个 blob 的时间戳和密钥。密钥以随机间隔定期更改,每次密钥更改时,都会将一组新密钥写入“密钥”表。有多个键,当将新的键集写入“键”表时,每个键都有一个具有相同时间戳的单独条目。

如果我这样做:

select distinct timestamp from keys;

每次旋转密钥时都会返回一个集合,并将新密钥集写入数据库。

我想要的是 mysql 中的一个 sql 语句,它返回每个键集的时间戳以及“值”表中每个键时间戳之间的记录总数。

例如:

Timestamp Count
1635962134 23
1636048054 450
1636145254 701

等等……

最后一行需要特别考虑,因为它的“当前”集在 keytable 中没有另一个条目(还......)

SQL Fiddle 与示例数据: SQL FIDDLE WITH SAMPLE DATA

对于上面的示例数据,结果应该是: |时间戳 |计数 | | --------- | ----- | | 1635962134 | 14| | 1636043734 | 28| | 1636119328 | 11|

【问题讨论】:

提供一些示例数据作为在线小提琴或 CREATE TABLE + INSERT INTO(~10-12 行)和该数据的所需输出。 【参考方案1】:

您受 mySQL 版本的限制,但您可以使用变量来帮助创建行集。您也可以使用连接来完成此操作,但会稍微复杂一些。

https://dbfiddle.uk/?rdbms=mysql_5.6&fiddle=b5d587b30f1a758ce31e3fa4745f26d0

SELECT k.key1, k.key2, count(*) as vol
FROM my_values v
JOIN (
  SELECT key_ts as key1, @curr-1 as key2, @curr:= key_ts
  FROM (
    SELECT DISTINCT key_ts FROM my_keys 
    JOIN (SELECT @curr:=9999999999) var
    ORDER BY key_ts DESC
  ) z
) k ON (v.val_ts BETWEEN k.key1 and k.key2)
GROUP BY key1, key2

首先(最里面的子查询)从 my_keys 中选择不同的时间戳并对其进行排序。我使用该连接只是为了设置变量。您也可以在单独的查询中使用 SET 语句。我将变量设置为任意高的时间戳,这样系列中的最后一个时间戳将始终有一个伙伴。

从中选择键和变量值减1(防止重叠),然后将变量设置为当前键。这必须在选择查询中的所有其他内容之后完成。这将生成两个成对的时间戳,代表一个时间范围。

然后只需将 my_values 加入这些键,并使用 BETWEEN 作为加入条件。

让我知道这是否适合你。

【讨论】:

哇。极好的。这很棒! “as vol”语句有什么作用? 只是一个别名,所以该字段被称为vol而不是count(*)。它在输出中看起来更好,而且如果您想在另一个查询中引用该字段,您需要一些东西来调用它。这解决了您的问题吗? 谢谢。是的,它解决了我的问题。我的人工数据中没有捕获的“真实”数据存在一个小问题,但我想我可以弄清楚。由于某种原因,它缺少一排。再次感谢!

以上是关于位于其他表中的值之间的计数的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

oracle sql中根据其他表中的计数重新启动rownumber

ORACLE SQL 查询从其他表中的行字符串匹配的行返回值

SQL:仅选择以给定间隔与其他结果分隔的值的行

用于计数和显示(列中的不同值)的 Sql 查询优化,按其他两列分组

JOIN 中的 SQL CASE 语句 - 当其他表中的值存在时

SQL 查询以获取每个经理下的员工的递归计数