将插值行插入现有表中

时间:2014-07-17 05:08:06

标签: mysql sql

我有一个类似于这个简化示例的MySQL表:

          orders table
--------------------------------
orderid stockid rem_qty reported
--------------------------------
1000000     100     500 00:01:00
1000000     100     200 01:10:00
1000000     100     200 03:20:00
1000000     100     100 04:30:00
1000000     100      50 11:30:00
:
1000010     100     100 00:01:00
1000010     100     100 01:10:00
1000010     100      20 03:20:00
:
1000020     200    1000 03:20:00
1000020     200     995 08:20:00
1000020     200     995 11:50:00
--------------------------------

该表来自第三方,每天重约80-100M行,格式固定。这将是好的,除了它 rem_qty 达到零时缺少行。好消息是,我可以估计它们,至少是一个好的上/下限:

第三方在一天中基本上随机时间扫描每个不同的 stockid ,并在那时为每个打开的 orderid 返回一行。例如,在(00:01, 01:10, 03:20, 04:30, 11:30)扫描了 stockid = 100 。每次每个当前 orderid 都会有一行 stockid 。因此,可以看到 orderid = 1000000 仍然在11:30(我们的数据中的最后一次扫描)打开,但有时在03:20和04:30之间, orderid = 1000010 < / em>售罄。 ( stockid = 200 的时间与 stockid = 100 无关。

所以,我想要做的是INSERT每个售罄订单的 rem_qty = 0 的插值行。在这种情况下,我们可以(仅)说 orderid = 1000010 AVG('03:20:00','04:30:00')处变为0,所以我想INSERT以下一行:

      orders table INSERT
--------------------------------
orderid stockid rem_qty reported
--------------------------------
1000010     100       0 03:55:00
--------------------------------

麻烦的是,我的SQL生锈了,我无法弄清楚这个复杂的查询。在其他失败的尝试中,我尝试了各种JOIN s,制作了TEMPORARY TABLE stock_report(stockid,last_report),我可以这样做:

SELECT      orders.stockid,
            orderid,
            MAX(reported),
            TIMEDIFF(last_report,MAX(reported)) as timediff
FROM        orders
INNER JOIN  stock_report
        ON  orders.stockid = stock_report.stockid
GROUP BY    orderid
HAVING      timediff > 0
ORDER BY    orderid

这将显示每个售罄的订单,以及上次报告 orderid 之间的HH:MM:SS差异,以及最后时间<报告了em> stockid 。这可能是一个好的开始,但我需要能够计算 next_report 列(特定于此 orderid ,而不是 last_report ,基本上是:

SELECT      MIN(reported) AS next_report
FROM        orders
WHERE       reported > @order_max_reported
ORDER BY    reported
LIMIT       1

但这只是徒劳地试图说明我所追求的一部分。同样,我真正需要的是在订单的 rem_qty 转到INSERT时将AVG()新行放入 orders()表的方法0,如上面的orders table INSERT示例表中所示。或者,也许是64,000 GFLOP问题:我会更好地将这种逻辑转移到我的主要(应用程序)语言吗?我正在以1亿行/天的速度工作,因此效率是一个问题。

为冗长的描述道歉。这真的是我能做的最好的编辑简洁!任何人都可以提供任何有用的建议吗?

1 个答案:

答案 0 :(得分:1)

可以这样做。有一个子查询获取每个订单ID /库存ID的最大报告时间,并将其与库存ID相同且最新时间小于订单时间的订单表连接。这将使您获得该股票ID的所有报告时间,该报告时间大于该股票ID和订单ID的最新时间。

使用MIN获得最低报告时间。将2次转换为秒,将它们加在一起并除以2,然后将其从秒转换回时间。

这样的事情: -

SELECT orderid, stockid, 0, SEC_TO_TIME((TIME_TO_SEC(next_poss_order_report) + TIME_TO_SEC(last_order_report)) / 2)
FROM
(
    SELECT a.orderid, a.stockid, last_order_report, MIN(b.reported) next_poss_order_report
    FROM 
    (
        SELECT orderid, stockid, MAX(reported) last_order_report
        FROM orders_table
        GROUP BY orderid, stockid
    ) a
    INNER JOIN orders_table b
    ON a.stockid = b.stockid
    AND a.last_order_report < b.reported
    GROUP BY a.orderid, a.stockid, a.last_order_report
) sub0;

SQL小提琴: -

http://www.sqlfiddle.com/#!2/cf129/17

可以简化这一点: -

SELECT a.orderid, a.stockid, 0, SEC_TO_TIME((TIME_TO_SEC(MIN(b.reported)) + TIME_TO_SEC(last_order_report)) / 2)
FROM 
(
    SELECT orderid, stockid, MAX(reported) last_order_report
    FROM orders_table
    GROUP BY orderid, stockid
) a
INNER JOIN orders_table b
ON a.stockid = b.stockid
AND a.last_order_report < b.reported
GROUP BY a.orderid, a.stockid, a.last_order_report;

这些查询可能需要一段时间,但可能比从脚本代码运行许多查询更有效。