我有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
答案 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;