Получение следующей строки с использованием SQL - PullRequest
1 голос
/ 22 марта 2010

У меня есть 1 таблица с данными таким образом:

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

Мне нужно найти все экземпляры значений Col2 с «A», за которым сразу следует «B». «А», за которым следует любой другой символ, не считается. Есть ли способ использовать 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 ]

3 голосов
/ 22 марта 2010

Учитывая, что не существует неявного упорядочения набора, нет, нет надежного способа сделать это. Ваши данные нужно будет упорядочить (возможно, по третьему столбцу или по столбцу 1), чтобы это имело какой-либо смысл.

1 голос
/ 22 марта 2010
 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'

Обновление : Как упоминалось ниже Питером Лангом, это не будет работать, если последовательность в 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'
1 голос
/ 22 марта 2010

Похоже, вы пытаетесь выяснить, кто получил оценку от А до В, поэтому мы также предполагаем, что вам нужны результаты, где В следует за А для того же администратора.

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 находят все записи, где «B» встречается после «A». Левое соединение 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. Вы также можете получить более одного набора записей для каждого пользователя.

0 голосов
/ 27 марта 2010

В этом запросе предполагается, что col1 - это некая последовательность или метка времени для каждой строки. Без этого невозможно определить, произошло ли А до или после Б.

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
;
0 голосов
/ 22 марта 2010

Я думаю, что следующее должно работать, учитывая, что ваш обновленный макет таблицы с 3 столбцами. (В противном случае это невозможно, потому что нет заказа):

select t1.col2
from yourtable t1, yourtable t2
where t1.col3 = 'A'
and t2.col3 = 'B'
and t1.col1 + 1 = t2.col1;
0 голосов
/ 22 марта 2010

Как вы сортируете столбцы? Если вы не сортируете их, вы можете получать разные результаты каждый раз, как иногда A следовал бы за B, а иногда B следовал бы за A. Если вы сортируете их, вы можете использовать тест «существует» с сортировкой выражение.

Не существует общего метода получения следующей (или предыдущей) строки в SQL, но многие реализации предоставляют свои собственные встроенные функции, чтобы помочь с такими вещами. К сожалению, я не знаком с DB2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...