使用SQL获取下一行

时间:2010-03-22 17:06:55

标签: sql db2

我有1个包含数据的表:

Col1      Col2  
------- --------  
Admin001  A  
Admin001  B  
Admin002  C   
Admin002  C  
Admin003  A  
Admin003  C

我需要找到所有Col2值的实例,其中'A'后跟'B'。 “A”后跟任何其他符号不计算在内。有没有办法使用SQL来实现这一目标?
环境是DB2 LUW v9.5

更新: 如果我按照下面那样制作表格怎么办?

Col1    Col2      Col3  
----    ------- --------  
1      Admin001     A  
2      Admin002     C   
3      Admin002     C  
4      Admin003     A  
5      Admin003     C
6      Admin001     B 
7      Admin001     A
8      Admin001     C
9      Admin001     B  

6 个答案:

答案 0 :(得分:3)

鉴于没有集合的隐式排序,那么不,没有任何可靠的方法来做到这一点。您的数据需要订购(可能需要通过第三栏或第1列),这样才有意义。

答案 1 :(得分:1)

看起来你正在试图找出从A到B的成绩从哪里下降,所以我们也假设你想要的结果是B对于同一个管理员来说是A。

SELECT DISTINCT t1.Col2
FROM table t1
INNER JOIN table t2 ON t1.Col2 = t2.Col2
LEFT OUTER JOIN table t3 ON t1.Col2 = t3.Col2
            AND t3.Col1 < t2.Col1 AND t3.Col1 > t1.Col1
WHERE t1.Col3 = 'A'
  AND t2.Col3 = 'B' AND t2.Col1 > t1.Col1
  AND t3.Col1 IS NULL

这会产生任何“A”后跟“B”的管理员。

INNER JOIN和WHERE子句中的前两个表达式查找“​​A”之后出现“B”的所有记录。左边的OUTER连接和WHERE子句中的最后一个表达式查找A和B之间有等级的所有记录,并且只记录没有的记录。

您要求获得这些结果,每行一个,如下所示:

Col1    Col2      Col3  
----    ------- --------  
1      Admin001     A  
6      Admin001     B

我将以简单的方式调整上述查询。

我只需获取A记录,获取B记录并将其合并:

(SELECT t1.Col1, t1.Col2, t1.Col3
FROM table t1
INNER JOIN table t2 ON t1.Col2 = t2.Col2
LEFT OUTER JOIN table t3 ON t1.Col2 = t3.Col2
            AND t3.Col1 < t2.Col1 AND t3.Col1 > t1.Col1
WHERE t1.Col3 = 'A'
  AND t2.Col3 = 'B' AND t2.Col1 > t1.Col1
  AND t3.Col1 IS NULL)
UNION
(SELECT t2.Col1, t2.Col2, t2.Col3
FROM table t1
INNER JOIN table t2 ON t1.Col2 = t2.Col2
LEFT OUTER JOIN table t3 ON t1.Col2 = t3.Col2
            AND t3.Col1 < t2.Col1 AND t3.Col1 > t1.Col1
WHERE t1.Col3 = 'A'
  AND t2.Col3 = 'B' AND t2.Col1 > t1.Col1
  AND t3.Col1 IS NULL)
ORDER BY Col2, Col1

请注意,我们首先按Col2排序,然后Col1排序。您还可以为每个用户获取多组记录。

答案 2 :(得分:1)

 SELECT DISTINCT T1.Col2 
 FROM Table T1 INNER JOIN Table T2
 ON T2.Col2 = T1.Col2 AND T2.Col1 = (T1.Col1 + 1)
 WHERE T1.Col3 = 'A' AND T2.Col3 = 'B'

更新:如下面的Peter Lang所述,如果Col1中的序列被中断,这将不起作用。这个版本处理这种情况并且更有保证产生正确的结果,尽管如果你100%确定序列不会被中断(也就是说,如果你自己在与分析相同的事务中生成序列),那么第一个应该是更快:

 SELECT DISTINCT T1.Col2 
 FROM Table T1 INNER JOIN Table T2
 ON T2.Col2 = T1.Col2 
 AND T2.Col1 = (SELECT MIN(Col1) FROM Table T3 WHERE T3.Col1 > T1.Col1)
 WHERE T1.Col3 = 'A' AND T2.Col3 = 'B'

答案 3 :(得分:0)

您如何对列进行排序?如果你没有对它们进行排序,你每次都会得到不同的结果,因为有时A会跟随B,有时B会跟随A.如果你要对它们进行排序,你可以使用“存在”测试进行排序表达

在SQL中没有获取下一行(或前一行)的通用方法,但是许多实现提供了自己的内置函数来帮助处理这类事情。不幸的是我不熟悉DB2。

答案 4 :(得分:0)

此查询假定col1是每行的某种序列或时间戳。没有它,就无法确定A是在B之前还是之后发生。

WITH sorted AS 
(SELECT col1, col2, col3, ROWNUMBER() 
    OVER (PARTITION BY col2 ORDER BY col1) AS col4
FROM sometable
)
SELECT a.col1, a.col2, a.col3, b.col1, b.col3
FROM sorted a INNER JOIN sorted b
ON a.col2 = b.col2
WHERE a.col3 = 'A' AND b.col3 = 'B'
AND b.col4 = a.col4 + 1
;

答案 5 :(得分:-1)

我认为以下内容应该可行,假设您的更新表布局有3列。 (否则这是不可能的,因为没有订购):

select t1.col2
from yourtable t1, yourtable t2
where t1.col3 = 'A'
and t2.col3 = 'B'
and t1.col1 + 1 = t2.col1;