我有一个数据库,在那里我存储了各种交易所产品的最佳出价和要价的1分钟快照.我有一个要求,我需要在哪里找到:

  1. 3种产品的500个最佳出价和要价(product1 & exch1,product2 & exch2,product3 & exch3)
  2. 所有500个数据点都应在一定的时间范围内,例如0900-1014、1030-1129
  3. 这3个产品应该有相同的时间戳,也就是说,如果prod1没有1030个数据点,那么查询应该忽略prod2和prod3&-100

我在Ubuntu 20.04上使用MySQL 8.0.35

我的表具有以下 struct

symbol(varchar)
exchange(varchar)
bid_price(double)
ask_price(double)
timestamp(bigint) # actual best bid ask received time from exchange (millisecond precision)
updated_at(bigint) # minutes precision stored as seconds since epoch e.g. 1702954500102
symbol,exchange,bid_price,ask_price,timestamp,updated_at
prod1,exch1,555.7,555.8,1702956540603,1702956540
prod1,exch1,555.8,555.9,1702956478591,1702956480
prod1,exch1,555.9,556,1702956420102,1702956420
prod1,exch1,556,556.1,1702956360610,1702956360
prod1,exch1,556,556.1,1702956299607,1702956300
prod1,exch1,556.1,556.2,1702956239595,1702956240
prod1,exch1,556.2,556.3,1702956179597,1702956180
prod1,exch1,556,556.1,1702956122111,1702956120
prod1,exch1,556,556.1,1702956061081,1702956060
prod1,exch1,555.8,555.9,1702955998590,1702956000
prod2,exch2,7.1041,7.1042,1702956600942,1702956600
prod2,exch2,7.104,7.1042,1702956541012,1702956540
prod2,exch2,7.1043,7.1045,1702956480465,1702956480
prod2,exch2,7.1043,7.1044,1702956420617,1702956420
prod2,exch2,7.1043,7.1044,1702956360264,1702956360
prod2,exch2,7.1037,7.1038,1702956300269,1702956300
prod2,exch2,7.1039,7.1041,1702956239092,1702956240
prod2,exch2,7.1041,7.1043,1702956180001,1702956180
prod2,exch2,7.1043,7.1045,1702956123891,1702956120
prod2,exch2,7.1045,7.1047,1702956060588,1702956060
prod3,exch3,72.78,72.79,1702956600332,1702956600
prod3,exch3,72.79,72.8,1702956540698,1702956540
prod3,exch3,72.8,72.81,1702956480542,1702956480
prod3,exch3,72.79,72.81,1702956420228,1702956420
prod3,exch3,72.8,72.81,1702956352133,1702956360
prod3,exch3,72.81,72.82,1702956287733,1702956300
prod3,exch3,72.81,72.82,1702956239441,1702956240
prod3,exch3,72.82,72.83,1702956179253,1702956180
prod3,exch3,72.81,72.82,1702956124140,1702956120
prod3,exch3,72.81,72.82,1702956058999,1702956060

通过下面的查询,我能够完成需求#1和#2,但#3是我还不能理解的东西

(SELECT *, FROM_UNIXTIME(updated_at, '%H%i') AS u_time
FROM algo_system.bbo_1min
WHERE
(
(symbol = 'prod1' AND exchange = 'exch1')
OR
(symbol = 'prod2' AND exchange = 'exch2')
OR
(symbol = 'prod3' AND exchange = 'exch3')
)
HAVING
(u_time >= 900 AND u_time <= 1014)
OR
(u_time >= 1030 AND u_time <= 1129)
ORDER BY TIMESTAMP DESC LIMIT 500)

Edit: From the image below, as can see the highlighted red section has prod2 and prod3 data for 21:00 but prod1 doesn't have, I want to remove the prod2 and prod3 data if there is no datapoint for prod1 at 21:00 enter image description here

推荐答案

子联接或WHERE EXISTS查询可以工作.一定要考虑性能--我不知道子查询是否会使您的工作变得太慢.

很抱歉没有在MySQL中回答.

下面是一个在MsSQL中使用内部连接的例子--您可以看到我在哪里稍微修改了一下,以说明MsSQL和MySQL之间的差异.你应该能够与这个 idea 工作.

SELECT 
    symbol,
    exchange,
    bid_price,
    ask_price,
    --timestamp,
    FORMAT(dateadd(S, convert(bigint, timestamp) / 1000, '1970-01-01'),'hhmm')+700 AS timestamp,
    --updated_at
    FORMAT(dateadd(S, convert(INT, updated_at), '1970-01-01'),'hhmm')+700 AS updated_at
into #tmp_db
FROM(
    values 
    ('prod1','exch1',7.1041,7.1042, '1702956600942',    '1702956600'), -- 1030 for testing
    ('prod1','exch1',555.7,555.8,   '1702956540603',    '1702956540'),
    ('prod1','exch1',555.8,555.9,   '1702956478591',    '1702956480'),
    ('prod1','exch1',555.9,556,     '1702956420102',    '1702956420'),
    ('prod1','exch1',556,556.1,     '1702956360610',    '1702956360'),
    ('prod1','exch1',556,556.1,     '1702956299607',    '1702956300'),
    ('prod1','exch1',556.1,556.2,   '1702956239595',    '1702956240'),
    ('prod1','exch1',556.2,556.3,   '1702956179597',    '1702956180'),
    ('prod1','exch1',556,556.1,     '1702956122111',    '1702956120'),
    ('prod1','exch1',556,556.1,     '1702956061081',    '1702956060'),
    ('prod1','exch1',555.8,555.9,   '1702955998590',    '1702956000'),
    ('prod2','exch2',7.1041,7.1042, '1702956600942',    '1702956600'), -- 1030 for testing
    ('prod2','exch2',7.104,7.1042,  '1702956541012',    '1702956540'),
    ('prod2','exch2',7.1043,7.1045, '1702956480465',    '1702956480'),
    ('prod2','exch2',7.1043,7.1044, '1702956420617',    '1702956420'),
    ('prod2','exch2',7.1043,7.1044, '1702956360264',    '1702956360'),
    ('prod2','exch2',7.1037,7.1038, '1702956300269',    '1702956300'),
    ('prod2','exch2',7.1039,7.1041, '1702956239092',    '1702956240'),
    ('prod2','exch2',7.1041,7.1043, '1702956180001',    '1702956180'),
    ('prod2','exch2',7.1043,7.1045, '1702956123891',    '1702956120'),
    ('prod2','exch2',7.1045,7.1047, '1702956060588',    '1702956060'),
    ('prod3','exch3',72.78,72.79,   '1702956600332',    '1702956600'), -- 1030 for testing
    ('prod3','exch3',72.79,72.8,    '1702956540698',    '1702956540'),
    ('prod3','exch3',72.8,72.81,    '1702956480542',    '1702956480'),
    ('prod3','exch3',72.79,72.81,   '1702956420228',    '1702956420'),
    ('prod3','exch3',72.8,72.81,    '1702956352133',    '1702956360'),
    ('prod3','exch3',72.81,72.82,   '1702956287733',    '1702956300'),
    ('prod3','exch3',72.81,72.82,   '1702956239441',    '1702956240'),
    ('prod3','exch3',72.82,72.83,   '1702956179253',    '1702956180'),
    ('prod3','exch3',72.81,72.82,   '1702956124140',    '1702956120'),
    ('prod3','exch3',72.81,72.82,   '1702956058999',    '1702956060')

) AS x (symbol, exchange, bid_price, ask_price, timestamp, updated_at)



SELECT top 500
    *
    --FROM_UNIXTIME(updated_at, '%H%i') AS u_time
FROM #tmp_db
JOIN (
        SELECT
            count(DISTINCT symbol) as product_count,
            updated_at as sub_updated_at
        FROM #tmp_db
        WHERE 
            (
                (symbol = 'prod1' AND exchange = 'exch1')
                OR
                (symbol = 'prod2' AND exchange = 'exch2')
                OR
                (symbol = 'prod3' AND exchange = 'exch3')
            )
        GROUP BY updated_at
    ) as x on x.product_count = 3 and x.sub_updated_at = updated_at
WHERE
    (
        (symbol = 'prod1' AND exchange = 'exch1')
        OR
        (symbol = 'prod2' AND exchange = 'exch2')
        OR
        (symbol = 'prod3' AND exchange = 'exch3')
    )
--HAVING
--  (updated_at >= 900 AND updated_at <= 1014)
--  OR
--  (updated_at >= 1030 AND updated_at <= 1129)
and (
        (updated_at >= 900 AND updated_at <= 1014)
        OR
        (updated_at >= 1030 AND updated_at <= 1129)
    )
ORDER BY updated_at DESC --LIMIT 500



drop table #tmp_db

all three if the prod1 is included enter image description here

none if the prod1 is not showing enter image description here

更新:增加了"不同的符号",以确保所有三种产品都被计算在内,以防一个产品可以显示不止一次.

Mysql相关问答推荐

创建从表中筛选数据的过程时出错

没有 ORDER BY 的查询性能很高,有 ORDER BY 的查询速度慢得像爬行一样

在两个日期之间生成每个月的1行数据.

如果存在N个特殊行,如何 Select 它们,其余的必须填充常规行,总行数不能超过MySQL中的X行?

如果其中一个表为空,则 mysql 中的查询会给出 0 个结果

MySQL 可以用于将列表排序为三分之三吗?

MySQL - 如何根据单列查找重复行?

如何在Mysql中使用With和Values

估计对大表进行分区所需的时间

如何在 MySQL 中查找重复值和更新值

在表中找到最大值,然后分别显示SQL组和每个SQL组中的最大值计数

具有别名主机的 ssh 反向 mysql tunel

MySQL查询根据同一表中其他字段的值更新表中的字段

如何使用 C++ 连接 mySQL 数据库

MySQL Group By 和 Sum 其他列的总值

用于国际和多语言目的的数据库建模

重新加载 .env 变量而不重新启动服务器(Laravel 5,共享主机)

phpmyadmin没有收到要导入的数据错误,如何解决?

如何存储重复日期牢记夏令时

如何将 mysqldump 的输出拆分为较小的文件?