选择多个列,但只选择列上具有“最大值”的行,并与不同的数据库连接

时间:2014-02-12 12:14:45

标签: sql greatest-n-per-group uniqueidentifier

我遇到了一个我无法解决的SQL查询问题。

我在第一张表中有一个包含订单的表格,订单号 唯一,如下所示:

+-------+------------+
| Order | Orderdate  |
+-------+------------+
| 10122 | 19.03.2013 |
| 10123 | 15.03.2013 |
| 10124 | 19.03.2013 |
| 10125 | 17.03.2013 |
| 10126 | 07.03.2013 |
| 10127 | 01.03.2013 |
| 10128 | 16.03.2013 |
| 10129 | 10.03.2013 |
| 10130 | 22.03.2013 |
+-------+------------+

第二个表包含订单的状态更新:

+---------+----------------+--------------+------------+
|  Order  |  Statuschange  |  Changedate  | Changetype |
+---------+----------------+--------------+------------+
|   10127 |             12 |              | Admin      |
|   10127 |              3 |  04.03.2013  | Packaging  |
|   10127 |              4 |  10.03.2013  | Shipping   |
|   10127 |              5 |  13.03.2013  | Packaging  |
|   10127 |              5 |  15.03.2013  | Shipping   |
|   10127 |              6 |  19.03.2013  | Admin      |
|   10127 |              7 |  24.03.2013  | Shipping   |
|   10127 |              8 |  25.03.2013  | Admin      |
|   10127 |              8 |  26.03.2013  | Packaging  |
|   10127 |              8 |  27.03.2013  | Admin      |
|   10127 |              8 |  29.03.2013  | Shipping   |
|   10127 |              8 |  30.03.2013  | Shipping   |
|   10127 |             12 |  01.07.2013  | Shipping   |
|   10127 |              8 |  02.07.2013  | Shipping   |
+---------+----------------+--------------+------------+

从该表中,我想获得statuschange中编号最高的行,如果有几个那么具有最高日期的那一行。 我还希望将此结果限制为一个Changetype,例如详情

问题是第二个表没有唯一标识符。

我的最终查询输出应如下所示:

+-------+------------+--------------+------------+------------+
| Order | Orderdate  | Statuschange | Changedate | Changetype |
+-------+------------+--------------+------------+------------+
| 10127 | 01.03.2013 |           12 | 01.07.2013 |  Shipping  |
+-------+------------+--------------+------------+------------+

到目前为止,我只能获得最高的状态更改,但不能同时更改日期和更改的状态编号。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

如果您的DBMS支持WITH子句和窗口函数,则可以使用

WITH a AS (
SELECT o.Order,
       o.Orderdate,
       s.Statuschange,
       s.Changedate,
       s.Changetype,
       Row_number() OVER(partition by o.Order
                         order by s.statuschange desc, s.changedate desc)
                 as no
  FROM Orders o
       JOIN Statuschange s ON o.Order = s.Order
 WHERE s.Changetype = 'Shipping'
)
SELECT Order,
       Orderdate,
       Statuschange,
       Changedate,
       Changetype
  FROM a
 WHERE no = 1

Row_number() over(...)在这里完成主要工作:它首先将结果集划分为分区,其中具有相同值o.Order的所有记录都到达同一分区。然后,在每个分区中,它会对从1开始的记录进行编号,首先按s.statuschange降序排序,将s.statuschange值按s.changedate降序排列。

最后,外部选择仅通过1子句排除所有没有数字WHERE的记录,这有效地返回具有最大changedate的记录statuschange 1}}为每个Order

这假设如下 - 您的问题并不完全清楚:

  • 您希望条目中每个订单的最大changedate 的最大statuschange条目。 (按字面意思阅读您的问题,您要求所有订单中changedate 最多statuschange的条目。如果这确实是您的请求,则应省略partition by o.Order。)
  • 您希望在结果中看到Changetype(您未说明,您的预期结果不包含此列)。

答案 1 :(得分:1)

;WITH ff AS
(
    SELECT ROW_NUMBER() OVER(PARTITION BY Order ORDER BY Statuschange DESC, Changedate DESC) num, *
    FROM [second table]
)
    SELECT f.Order, f.Orderdate, s.Statuschange, s.Changedate  
    FROM [first table] f
    LEFT JOIN  ff s on f.Order = s.Order AND s.num > 1