确定行之间的特定条件

时间:2015-11-12 06:26:18

标签: sql postgresql

我在PostgreSQL中有表格如下:

logid | transactionid | partid | qty  | refid
------+---------------+--------+------+------
 100  |      3        |    50  |   10 | 5555
 101  |      2        |    25  |   5  | 5812
 102  |      3        |    50  |   20 | 5844
 103  |      3        |    10  |  200 | 1234
 104  |      3        |    10  |  100 | 0
 105  |      3        |    10  | -150 | 1234

我想写一个查询,它给出: 行transactionid = 3的行,当同一logidpartid的{​​{1}}有两个refid <> 0下一个 refid = 0时。

我想得到的上述数据:

103   |      3         |    10  |  200  | 1234
104   |      3         |    10  |   100 | 0

2 个答案:

答案 0 :(得分:2)

您可以使用LAG and LEAD窗口函数来获取所需的结果集:

SELECT logid, transactionid, partid, qty, refid
FROM (
  SELECT logid, transactionid, partid, qty, refid,
         LAG(partid) OVER (ORDER BY logid) AS prev_partid,
         LAG(refid) OVER (ORDER BY logid) AS prev_refid,  
         LEAD(partid) OVER (ORDER BY logid) AS next_partid,
         LEAD(refid) OVER (ORDER BY logid) AS next_refid
  FROM mytable
  WHERE transactionid = 3) AS t
WHERE (partid = next_partid AND refid <> 0 AND next_refid = 0) OR
      (partid = prev_partid AND refid = 0 AND prev_refid <> 0)

使用这些函数,我们可以识别具有相同partid值的连续行。我们还可以轻松地为上一行/下一行实现refid <> 0refid = 0谓词。

Demo here

答案 1 :(得分:0)

select * from (
select *, ((lead(a1) over(partition by partid  order by logid ) = true  ) and refid <> 0 ) a2 
     from (select * , case when refid = 0 then ( lag(refid) over(partition by partid order by logid ) <> 0  ) else null end  A1
                from mytable where transactionid = 3 order by logid 
           )q1 order by logid) q2 where a1 or a2   

也许这有点简单?希望这也有效