2012-08-03 45 views
0

作为SQL noob,我有一个我假设的基本问题,即关于1到多个子记录的基本问题。使用父数据从单个子记录返回数据(按日​​期排序)

我有一个订单表和一个Order_Status子表。

Order table 
ID Order_Number Status Order_Date ect 

Order_Status table 
StatusTo StatusFrom Order_ID StatusChange_Date 

子表可以具有许多状态更改为单亲订单的实体。

如何将以下信息作为单个记录与该父级(p)的子表的(os)最新记录进行回拉? (p.Order_Number, p.Status, p.Order_Date, os.StatusTo, os.StatusChange_Date)。

我需要知道,因为我担心最后的os.statusto与p.status不匹配。

在此先感谢!

史蒂夫

+0

Sql Server的哪个版本是? – 2012-08-03 14:19:52

+0

你是对的,担心他们不匹配,这是违反规范化的做法。你可能会有更好的时间用更传统的历史表(不必仅仅存储状态),你只需列出它以前的内容(显然与变化时间戳一起)。 – 2012-08-03 15:37:50

回答

0

你可以加入到一个子查询它获取最新的订单状态

例如

SELECT p.Order_Number, p.Status, p.Order_Date, os.StatusTo, os.StatusChange_Date 
FROM ORDER p 
LEFT JOIN (
      SELECT StatusTo, Order_ID, MAX(StatusChange_Date) as StatusChange_Date 
      FROM Order_Status 
      GROUP BY StatusTo, Order_ID 
     ) os ON os.Order_ID= p.Order_ID 
+0

这不起作用,因为派生表必须首先获取每个Order_ID的最后日期,然后再返回到Order_Status以从此行检索StatusTo,然后才能继续执行订单。对于Order_ID,这种派生表将为Order_Status中的每个状态返回一行。 – 2012-08-03 14:30:56

+0

嗯你是对的。 – MakkyNZ 2012-08-03 14:39:44

+0

(对不起格式)我可不要这样做:'选择p.Order_Number,p.Status,p.Order_Date,os.StatusTo,os。StatusChange_Date FROM阶数p LEFT JOIN( SELECT TOP 1 StatusTo,Order_ID上,MAX(StatusChange_Date)作为StatusChange_Date FROM ORDER_STATUS ORDER BY StatusDateChange递减 )OS上os.Order_ID = p.Order_ID' – 2012-08-03 15:37:49

0

我相信这应该有效。假设你只关心那些有变化的订单,以及变化与记录不同的地方(应该是微不足道的修改)。

WITH Most_Recent_Change (order_id, statusTo, changedAt, rownum) as 
    (SELECT order_id, statusTo, statusChange_date, 
      ROWNUMBER() OVER(PARTITION BY order_id 
           ORDER BY statusChange_date DESC) 
     FROM Order_Status) 
SELECT Order.order_number, Order.status, Order.order_date, 
     Most_Recent_Change.statusTo, Most_Recent_Change.changedAt 
FROM Order 
JOIN Most_Recent_Change 
ON Most_Recent_Change.order_id = Order.id 
AND Most_Recent_Change.rownum = 1 
AND Most_Recent_Change.statusTo <> Order.status 

(将有SQLFiddle例子,但它的行事怪异的时刻)

请注意,您应该谨慎的承诺水平,你在运行这个,否则你可能会得到来自行误报正在同时更新。

其他说明:

  • 不要使用保留字(如ORDER)标识符。这只是一个普遍的麻烦
  • 不要为它们的数据类型加后缀,特别是如果这些类型将来可能会改变。我知道order_date不是严格这种方式命名,但它危险地关闭。它可能应该是orderedOn(如果是严格的“太阳日”类型)或更好的orderedAt(时间戳,UTC或带时区)。
+0

谢谢,我会试试这个。另外,我的“合作伙伴”做了命名约定,不是我会做的事情(但是后来我知道它的名字很奇怪)。 – 2012-08-03 19:00:49

+0

SQL Server不喜欢这个查询的OVER(ORDER ...)部分。 - 史蒂夫 – 2012-08-03 19:19:47

+0

@ Stephen.Britz - 对不起,我似乎有'PARTITION'和'ORDER BY'子句的顺序(heh)交换。 – 2012-08-03 19:51:46