过滤SQL查询?

时间:2014-03-19 18:19:41

标签: sql sql-server

示例数据为:

 
l16seqno | l16lcode | carrno | ecarrno | l16qty | reasoncode
32001 | 12 | 207620 | 370036873034035916 | 32 | 0
32269 | 12 | 207620 | 370036873034035916 | -32 | 800
39075 | 12 | 207620 | 370036873034035916 | 32 | 0
39074 | 12 | 207622 | 370036873034035923 | 32 | 0
32268 | 12 | 207622 | 370036873034035923 | -32 | 800
31999 | 12 | 207622 | 370036873034035923 | 32 | 0
32271 | 12 | 207624 | 370036873034035930 | -32 | 800
32005 | 12 | 207624 | 370036873034035930 | 32 | 0
39077 | 12 | 207624 | 370036873034035930 | 32 | 0

我记录了表Z02T1中的所有事件。每当我有l16lcode = 12时 - 我正在阻塞或解锁托盘。当我阻止一个托盘l16lqty feild是负面的,当我解锁时 - 它是正面的。

原因代码可以在Z02T2表中找到(可以通过l16seqno连接到Z02T1 - 每个日志记录的唯一序列号)。

Z14T1表包含有关托盘 - 托盘编号的信息。

我的目标是为每个托盘找到两条线,即

在使用代码800阻止时......以及......在使用代码0解锁时

为此,我必须找到最近的l16lcode = 12的下一条记录,对于相同的托盘,原因码为0(在此托盘的记录之后,原因码为800)。

我所做的初步查询是:

select   Z02T1.datreg, Z02T1.l16seqno, Z02T1.l16lcode, Z02T1.divcode, Z02T1.carrno,
       Z14T1.ecarrno, Z02T1.l16qty, Z02T2.reascode from Z02T2
inner join Z02T1 on Z02T1.l16seqno=Z02T2.l16seqno
left outer join Z14T1 ON Z14T1.carrno=Z02T1.carrno
where Z02T1.l16lcode=12 
and (Z02T2.reascode=800 or Z02T2.reascode=0 )
order by Z14T1.ecarrno

我如何更改此查询以获取一条带有 reasoncode 800 的记录,然后使用原因码0 获取同一 ecarrno feild 的下一条记录?

2 个答案:

答案 0 :(得分:0)

你走了:

;with cte as
(
    Select  l16seqno
            ,l16lcode
            ,carrno
            ,ecarrno
            ,l16qty
            ,reasoncode
            ,ROW_NUMBER() Over(Partition By ecarrno, reasoncode Order By l16seqno) rn
    From    MyTable
)
Select  l16seqno
        ,l16lcode
        ,carrno
        ,ecarrno
        ,l16qty
        ,reasoncode
From    cte
Where   rn = 1
Order By ecarrno asc, reasoncode desc

答案 1 :(得分:0)

以下是一些可用于修改现有查询的示例代码。

请注意,此示例会对reasoncode=800的第一次出现进行过滤,然后在reasoncode=0的第一次出现时过滤子过滤器,其l16seqno大于reasoncode=800记录。

CREATE TABLE reasons (
  l16seqno int NOT NULL,
  carrno int NOT NULL,
  reasoncode int NOT NULL
  );

INSERT INTO reasons
  (l16seqno, carrno, reasoncode)
VALUES
  (1, 1, 0),
  (2, 1, 800),
  (3, 1, 0),
  (10, 300, 0),
  (11, 300, 800),
  (12, 300, 0),
  (13, 300, 800),
  (14, 300, 0),
  (1003, 1212, 0),
  (1004, 1212, 800),
  (1005, 1212, 0),
  (1006, 1212, 0);

WITH cte1 (l16seqno, carrno, reasoncode, rownumber)
AS
(
  SELECT l16seqno, carrno, reasoncode, ROW_NUMBER() OVER (PARTITION BY carrno, reasoncode ORDER BY l16seqno)
  FROM reasons
  WHERE reasoncode = 800
),
cte2 (l16seqno, carrno, reasoncode, rownumber)
AS
(
  SELECT r.l16seqno, r.carrno, r.reasoncode, ROW_NUMBER() OVER (PARTITION BY r.carrno, r.reasoncode ORDER BY r.l16seqno)
  FROM reasons AS r
  INNER JOIN cte1 AS c ON r.carrno = c.carrno
  WHERE r.reasoncode = 0 AND r.l16seqno > c.l16seqno
)
SELECT r.l16seqno, r.carrno, r.reasoncode
FROM reasons AS r
LEFT OUTER JOIN cte1 AS c1 ON c1.l16seqno = r.l16seqno
LEFT OUTER JOIN cte2 AS c2 ON c2.l16seqno = r.l16seqno
WHERE c1.rownumber = 1
OR c2.rownumber = 1
ORDER BY r.carrno, r.l16seqno;

以下是上面列出的示例代码的SQL Fiddle demo

我希望这会有所帮助。

相关问题