编辑1(说明):谢谢你到目前为止的答案!回应令人欣慰。
我想澄清一点问题,因为根据答案我认为我没有正确描述问题的一个方面(而且我确定这是我的错,因为即使对我自己也难以定义它)。
这里的问题:结果集应该只包含tstamp BETWEEN'2010-01-03'和'2010-01-09'的记录,以及一个记录,其中第一个order_num的tstamp为NULL设置(有总是是一个与每个order_num为空tstamp)。
到目前为止给出的答案似乎包括所有记录为某一order_num如果有任何与tstamp BETWEEN'2010-01-03'和'2010-01-09'。例如,如果另一条记录的order_num = 2和tstamp = 2010-01-12 00:00:00,则应将而不是包含在结果中。比使用“A UNION(B in A)”更高效的SQL?
原始问题:
考虑包含ID(唯一的),order_num,TSTAMP(时间戳)的订单表,和ITEM_ID(包含在订单单项目)。 tstamp为空,除非订单已被修改,在这种情况下,存在具有相同order_num和tstamp的另一条记录,然后包含发生更改时的时间戳。
例...
id order_num tstamp item_id __ _________ ___________________ _______ 0 1 100 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
什么是最有效的SQL语句一定的日期范围内检索所有已修改一次或多次的订单(基于order_num)的?换句话说,对于每个订单,我们需要所有具有相同order_num的记录(包括具有NULL tstamp的记录),对于每个order_num WHERE至少有一个order_num具有tstamp NOT NULL AND tstamp BETWEEN'2010-01-03' AND'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');
我很好奇提供的查询的性能,也许你可以分享测试结果? – 2010-01-22 21:38:53
我会尽快报告最终解决方案的性能改进情况 - 这很重要。 – machinatus 2010-01-25 15:03:21