0

在 SQL Server 中,我有一个表(我们称之为TransList),如下所示:

TPN    Start    End    TDate                      DoneBy
10     6        7      2003-03-17 14:48:42.750    User2 *
10     1        6      2003-03-13 08:02:09.317    User3
11     3        6      2003-03-21 08:15:45.410    User3 ** yes
11     6        3      2003-03-13 08:13:13.920    User4 <--
11     5        6      2003-03-08 17:39:51.460    User4
12     13       3      2003-03-19 10:58:23.187    User8 *
12     6        13     2003-03-17 14:48:42.750    User7
12     3        6      2003-03-13 08:02:09.317    User6
12     1        3      2003-03-01 14:09:17.167    User1
13     3        6      2003-03-19 10:58:23.187    User1 *** no
13     1        3      2003-03-01 14:09:17.167    User2 <--
14     3        6      2003-03-21 08:15:45.410    User5 ** yes
14     13       3      2003-03-13 08:13:13.920    User6 <--
14     6        13     2003-03-08 17:39:51.460    User7
15     6        3      2003-03-17 14:48:42.750    User2 *
15     1        6      2003-03-13 08:02:09.317    User3

这是一个非常复杂的查询的结果,它连接了两个单独的 SELECT 语句,每个语句连接了几个表。行按 排序TPN ASC, TDate DESC

我现在想过滤这个表并获得:

TPN    Start    End    TDate                      DoneBy
10     6        7      2003-03-17 14:48:42.750    User2
11     3        6      2003-03-21 08:15:45.410    User3
12     13       3      2003-03-19 10:58:23.187    User8
14     3        6      2003-03-21 08:15:45.410    User5
15     6        3      2003-03-17 14:48:42.750    User2

那是:

  • 每个选定 TPN 的最新交易
  • TPN 是根据其最新交易和/或其两个最新交易的条件选择的

标有 的行在*那里,因为(Start=6 and End=7) or (Start=13 and End=3) or (Start=6 and End=3)因此我不关心这些 TPN 的其他交易

标有 的行在**那里是因为(Start=3 and End=6) and for previous transaction (Start=6 and End=3)

标有***的行存在,因为(Start=3 and End=6) but for previous transaction is not (Start=6 and End=3)

我可能需要根据哪个用户进行了先前的交易和/或对 and 有更复杂的逻辑条件***状态机很复杂,我还没有完成检查),但***始终是not **.

我总是只需要检查每个 TPN 的前 2 个交易。

我是 SQL 新手,我已经花了几天时间来尝试弄清楚如何实现这一点。我考虑过自我加入TransList,使用 LIMIT 或 TOP 或走过桌子,但我没有设法使任何这个解决方案发挥作用。

任何人都可以帮忙吗?

编辑:
上面的表格是一个“摘录”,但为了响应安德烈的请求,这里是查询:

SELECT Items.[TPN],
       [StartStatus],
       [EndStatus],
       [TransactionDate],
       [TransDoneBy],
       [CurrentStatus],
       [Title],
       [Severity],
       [LastChangeDate],
       [ChangeDoneBy],
       [Planned],
       [Remaining]
FROM
(SELECT WORKITEM as 'TPN',
       TFIELDCHANGE.NEWSYSTEMOPTIONID as 'StartStatus',
       TFIELDCHANGE.OLDSYSTEMOPTIONID as 'EndStatus',
       THISTORYTRANSACTION.LASTEDIT as 'TransactionDate',
       trans_person.LASTNAME as 'TransDoneBy'
FROM dbo.THISTORYTRANSACTION JOIN dbo.TFIELDCHANGE ON (dbo.THISTORYTRANSACTION.OBJECTID = dbo.TFIELDCHANGE.HISTORYTRANSACTION)
                             JOIN dbo.TPERSON  trans_person ON (dbo.THISTORYTRANSACTION.CHANGEDBY = trans_person.PKEY)
WHERE dbo.TFIELDCHANGE.FIELDKEY = 4 -- Only transactions regarding status
) Transactions
JOIN
(SELECT WORKITEMKEY as 'TPN',
       TSTATE.LABEL as 'CurrentStatus',
       PACKAGESYNOPSYS as 'Title',
       TSEVERITY.LABEL as 'Severity',
       TWORKITEM.LASTEDIT as 'LastChangeDate',
       item_person.LASTNAME as 'ChangeDoneBy',
       max(CASE TATTRIBUTEVALUE.FIELDKEY WHEN 60 THEN TATTRIBUTEVALUE.INTEGERVALUE END) as 'Planned',
       max(CASE TATTRIBUTEVALUE.FIELDKEY WHEN 72 THEN TATTRIBUTEVALUE.INTEGERVALUE END) as 'Remaining'
FROM dbo.TWORKITEM JOIN dbo.TSTATE ON (dbo.TWORKITEM.STATE = dbo.TSTATE.PKEY)
                   JOIN dbo.TSEVERITY ON (dbo.TWORKITEM.SEVERITYKEY = dbo.TSEVERITY.PKEY)
                   JOIN dbo.TPERSON item_person ON (dbo.TWORKITEM.CHANGEDBY = item_person.PKEY)
                   JOIN dbo.TATTRIBUTEVALUE ON (dbo.TWORKITEM.WORKITEMKEY = dbo.TATTRIBUTEVALUE.WORKITEM)
WHERE dbo.TWORKITEM.STATE = 2 OR -- Current state: analyzed
      dbo.TWORKITEM.STATE = 3 OR -- Current state: assigned
      dbo.TWORKITEM.STATE = 4 OR -- Current state: suspended
      dbo.TWORKITEM.STATE = 6 OR -- Current state: implemented
      dbo.TWORKITEM.STATE = 7 OR -- Current state: verified
      dbo.TWORKITEM.STATE = 13   -- Current state: verifying
GROUP BY WORKITEMKEY,
         TSTATE.LABEL,
         PACKAGESYNOPSYS,
         TSEVERITY.LABEL,
         TWORKITEM.LASTEDIT,
         item_person.LASTNAME
) Items
ON Items.TPN = Transactions.TPN
ORDER BY Items.[TPN] ASC, [TransactionDate] DESC
4

1 回答 1

2

您似乎正在寻找一种通用方法来比较组的最新交易与其前身。

This can be done using the ROW_NUMBER() function and a self join like this:

SELECT foo
FROM   (SELECT foo,
               Row_number() OVER (PARTITION BY TRN ORDER BY TDate) AS RN
        FROM   TranTable) AS Latest
       LEFT JOIN (SELECT foo,
                         Row_number() OVER (PARTITION BY TRN ORDER BY TDate) AS RN
                  FROM   TranTable) AS Previous
         ON Latest.RN = Previous.RN - 1
WHERE  Latest.RN = 1 /* Get only the latest */
       OR (/* your criteria for two latest */ AND Latest.RN IN (1,2))
于 2012-06-14T17:13:03.573 回答