一尘不染

比使用“ UNION(A中的B)”更有效的SQL。

sql

编辑1(澄清): 谢谢您到目前为止的回答!回应令人欣慰。
我想澄清一下这个问题,因为基于答案,我认为我没有正确描述问题的一个方面(并且我确信这是我的错,因为即使我自己也很难定义它)。
这里的难题是:结果集应包含BETWEEN“2010-01-03”和“2010-01-09” TSTAMP只有记录,以及 一个
记录,其中TSTAMP是在第一组中的每个order_num NULL(会有对于每个order_num, 始终 为tstamp为空)。
到目前为止给出的答案似乎包含某个order_num的 所有 记录(如果 有的话) 与tstamp在“ 2010-01-03”和“
2010-01-09”之间进行比较。例如,如果存在与order_num = 2和TSTAMP另一个记录= 2010-01-12 00:00:00它应该
被包含在结果中。

原始问题:
考虑一个包含id(唯一),order_num,tstamp(时间戳)和item_id(订单中包含的单个商品)的订单表。tstamp为null,除非已修改订单,否则该订单中会有另一条具有相同order_num的记录,然后tstamp包含更改发生的时间戳。

例子…

id order_num tstamp item_id
__________________________
 0 1100
 1 2 101
 2 2 2010-01-05 12:34:56 102
 3 3 113
 4 4 124
 5 5 135
 6 5 2010-01-07 01:23:45 136
 7 5 2010-01-07 02:46:00 137
 8 6 100
 9 6 2010-01-13 08:33:55 105

检索在特定日期范围内被修改一次或多次的所有订单(基于order_num)的最有效的SQL语句是什么?换句话说,对于每个订单,我们需要所有具有相同order_num的记录(包括带有tstamp为NULL的记录),对于每个order_num,其中至少order_num的其中一个具有tstamp
NOT NULL和tstamp在‘2010-01-03’之间和“ 2010-01-09”。这是我遇到的“至少在order_num的其中一个具有tstamp
NOT NULL的地方”。

结果集应如下所示:

id order_num tstamp item_id
__________________________
 1 2 101
 2 2 2010-01-05 12:34:56 102
 5 5 135
 6 5 2010-01-07 01:23:45 136
 7 5 2010-01-07 02:46:00 137

我想出的SQL是这样的,它本质上是“ A UNION(A中的B)”,但是它执行缓慢,我希望有一个更有效的解决方案:

SELECT history_orders.order_id, history_orders.tstamp, history_orders.item_id
FROM
   (SELECT orders.order_id, orders.tstamp, orders.item_id
    FROM orders
    WHERE orders.tstamp BETWEEN '2010-01-03' AND '2010-01-09')
    AS history_orders
UNION
SELECT current_orders.order_id, current_orders.tstamp, current_orders.item_id
FROM
   (SELECT orders.order_id, orders.tstamp, orders.item_id
    FROM orders
    WHERE orders.tstamp IS NULL)
    AS current_orders
WHERE current_orders.order_id IN
   (SELECT orders.order_id
    FROM orders
    WHERE orders.tstamp BETWEEN '2010-01-03' AND '2010-01-09');

阅读 150

收藏
2021-05-23

共1个答案

一尘不染

也许是一个子查询:

select * from order o where o.order_num in (select distinct
  order_num from order where tstamp between '2010-01-03' and '2010-01-09')
2021-05-23