ROW_NUMBER以在PARTITION上生成具有重复的Order By value

问题描述 投票:0回答:1

我正在访问SQL Server中从应用程序按以下方式存储的视图

SELECT *
FROM
    (
        VALUES 
            (1, 'Open', { ts '2020-01-10 23:56:12' }), 
            (1, 'Started', { ts '2020-01-10 23:56:12' }), 
            (1, 'Hold', { ts '2020-01-10 23:56:12' }), 
            (1, 'Sent', { ts '2020-01-11 15:33:22' }), 
            (1, 'Complete', { ts '2020-01-11 15:36:22' }), 
            (1, 'Closed', { ts '2020-01-13 16:43:33' }), 
            (2, 'Open', { ts '2020-02-22 06:43:33' }), 
            (2, 'Started', { ts '2020-02-22 06:43:33' }), 
            (2, 'Clarify', { ts '2020-03-23 08:33:53' }), 
            (2, 'Closed', { ts '2020-03-24 08:33:53' })
        ) t (WO, WO_Status, WO_Status_Date)

这将产生以下内容

| WO | WO_Status | WO_Status_Date          |
+----+-----------+-------------------------+
| 1  | Open      | 2020-01-10 23:56:12.000 |
| 1  | Started   | 2020-01-10 23:56:12.000 |
| 1  | Hold      | 2020-01-10 23:56:12.000 |
| 1  | Sent      | 2020-01-11 15:33:22.000 |
| 1  | Complete  | 2020-01-11 15:36:22.000 |
| 1  | Closed    | 2020-01-13 16:43:33.000 |
| 2  | Open      | 2020-02-22 06:43:33.000 |
| 2  | Started   | 2020-02-22 06:43:33.000 |
| 2  | Clarify   | 2020-03-23 08:33:53.000 |
| 2  | Closed    | 2020-03-24 08:33:53.000 |

我只想根据行的固有顺序创建行号/ WO。

所以我想要的输出是

| WO | WO_Status | WO_Status_Date          | Order |
+----+-----------+-------------------------+-------+
| 1  | Open      | 2020-01-10 23:56:12.000 | 1     |
| 1  | Started   | 2020-01-10 23:56:12.000 | 2     |
| 1  | Hold      | 2020-01-10 23:56:12.000 | 3     |
| 1  | Sent      | 2020-01-11 15:33:22.000 | 4     |
| 1  | Complete  | 2020-01-11 15:36:22.000 | 5     |
| 1  | Closed    | 2020-01-13 16:43:33.000 | 6     |
| 2  | Open      | 2020-02-22 06:43:33.000 | 1     |
| 2  | Started   | 2020-02-22 06:43:33.000 | 2     |
| 2  | Clarify   | 2020-03-23 08:33:53.000 | 3     |
| 2  | Closed    | 2020-03-24 08:33:53.000 | 4     |

为此,我尝试了以下操作

SELECT
    a.*,
    ROW_NUMBER() OVER (PARTITION BY (a.[WO]) ORDER BY a.[WO_Status_Date] ASC) AS [Natural Order]
FROM
    (SELECT *
     FROM
         (VALUES 
            (1, 'Open', { ts '2020-01-10 23:56:12' }), 
            (1, 'Started', { ts '2020-01-10 23:56:12' }), 
            (1, 'Hold', { ts '2020-01-10 23:56:12' }), 
            (1, 'Sent', { ts '2020-01-11 15:33:22' }), 
            (1, 'Complete', { ts '2020-01-11 15:36:22' }), 
            (1, 'Closed', { ts '2020-01-13 16:43:33' }), 
            (2, 'Open', { ts '2020-02-22 06:43:33' }), 
            (2, 'Started', { ts '2020-02-22 06:43:33' }), 
            (2, 'Clarify', { ts '2020-03-23 08:33:53' }), 
            (2, 'Closed', { ts '2020-03-24 08:33:53' })
        ) t (WO, WO_Status, WO_Status_Date)
    ) a

产生此结果:

| WO | WO_Status | WO_Status_Date          | Natural Order |
+----+-----------+-------------------------+---------------+
| 1  | Started   | 2020-01-10 23:56:12.000 | 1             |
| 1  | Hold      | 2020-01-10 23:56:12.000 | 2             |
| 1  | Open      | 2020-01-10 23:56:12.000 | 3             |
| 1  | Sent      | 2020-01-11 15:33:22.000 | 4             |
| 1  | Complete  | 2020-01-11 15:36:22.000 | 5             |
| 1  | Closed    | 2020-01-13 16:43:33.000 | 6             |
| 2  | Started   | 2020-02-22 06:43:33.000 | 1             |
| 2  | Open      | 2020-02-22 06:43:33.000 | 2             |
| 2  | Clarify   | 2020-03-23 08:33:53.000 | 3             |
| 2  | Closed    | 2020-03-24 08:33:53.000 | 4             |

ORDER BY正在覆盖具有重复值的行的固有顺序。有没有一种方法可以通过,从而获得理想的结果。

sql-server tsql row-number
1个回答
0
投票

首先,您应该知道,当涉及到关系数据库时,没有“自然顺序”之类的东西。这是一个误解。实际上,这是一种常见的误解,我为此写了一篇blog post,因为即使在如此多的网站上有如此多的专业人士对此进行了多次反驳,但仍然有太多的开发人员成为这种误解的受害者。 >

现在,我假设应该根据业务逻辑顺序规则对不同的状态进行排序-可以使用包含表的状态表来对状态进行排序,也可以使用order by子句。

此SQL语句将为您提供所需的结果(假设我正确掌握了不同状态的顺序):

SELECT  WO, 
        WO_Status, 
        WO_Status_Date,
        ROW_NUMBER() OVER(PARTITION BY WO ORDER BY 
            WO_Status_Date, 
            CASE WO_Status 
                WHEN 'Open' Then 1
                WHEN 'Started' Then 2
                WHEN 'Hold' Then 3
                WHEN 'Clarify' Then 4
                WHEN 'Sent' Then 5
                WHEN 'Complete' Then 6
                WHEN 'Closed' Then 7
            END) As [Natural Order]
FROM
(
    VALUES 
        (1, 'Open', { ts '2020-01-10 23:56:12' }), 
        (1, 'Started', { ts '2020-01-10 23:56:12' }), 
        (1, 'Hold', { ts '2020-01-10 23:56:12' }), 
        (1, 'Sent', { ts '2020-01-11 15:33:22' }), 
        (1, 'Complete', { ts '2020-01-11 15:36:22' }), 
        (1, 'Closed', { ts '2020-01-13 16:43:33' }), 
        (2, 'Open', { ts '2020-02-22 06:43:33' }), 
        (2, 'Started', { ts '2020-02-22 06:43:33' }), 
        (2, 'Clarify', { ts '2020-03-23 08:33:53' }), 
        (2, 'Closed', { ts '2020-03-24 08:33:53' })
    ) t (WO, WO_Status, WO_Status_Date)
© www.soinside.com 2019 - 2024. All rights reserved.