Sprawdzanie ilości wystąpień danej wartości w sekwencji

0

Witam wszystkich,
pobieram sobie z tabeli rekordy dotyczące danego usera. W zależności od usera mam kilka, kilkanaście lub więcej rekordów. W każdym z nich jest pole z literą T lub N. Czyli np:

user kontakt
12345 T
12345 T
12345 N
12345 T
12345 T
12345 T
12345 N
12345 N

Interesuje mnie sprawdzenie czy dana wartość pola "kontakt" (T lub N) występuje w sekwencji 3 wystąpień nierozdzielonych inną wartością. Warunek ten spełnia wartość T, natomiast wartość N nie spełnia (bo choć występuje 3 razy ale jest rozdzielona przez 3xT).
Mam nadzieję, że w miarę jasno to opisałem. Potrzebuję pomocy/wskazówki w jaki sposób mogę sprawdzać czy dane sekwencje wystąpień określonej wartości nie są "przerwane" inną wartością.

Pozdrawiam

0

W bazie SQL nie ma danych uporządkowanych , dopiero użycie klauzuli "order by" definiuje porządek danych otrzymanych w wyniku zapytania. Bez niej kolejność danych w wyniku może być zupełnie przypadkowa

0

Ok. Zgadza się. Ta tabelka, która służy zobrazowaniu mojego problemu jest wynikiem innego zapytania, które ma już ustawione order by (wg chronologii zdarzeń).

0

A co jeśli jest więcej niz 3 wystąpienia, wtedy jest poprawnie czy nie?

0

Jak najbardziej poprawnie. Chodzi o to żeby odrzucać tych userów, którzy nie spełniają określonej ilości wystąpień tej samej wartości jeden po drugim. Pojawienie się wartości przeciwnej "kasuje licznik" i "rozpoczyna go od nowa" aż do wyczerpania wszystkich wystąpień albo znalezienia przynajmniej 3xT lub 3xN występujących jedno pod drugim.

0

która wersja SQL-a

0

2014

0

oczekujesz tego w jednym zapytaniu czy dopuszczasz manipulacje na danych i jak rozróżniasz kolejność...

1

Zmieniłem trochę dane testowe dodałem kolumne rn (numer wiersza), bo muszę wiedzieć wg. czego wymuszać kolejność:

rn usr kontakt
1 12345 T
2 12345 T
3 12345 N
4 12345 T
5 12345 T
6 12345 T
7 12345 N
8 12345 N

Właściwie cała akcja opiera się o połączeniu kolumny kontakt w jeden ciąg i sprawdzić, czy istnieje interesująca nas sekwencja.
Ważne przy tym, aby łączenie odbywalo sie w odpowiedniej kolejności, używam myku z FOR XML PATH do konkatenacji.
dla czystości zapisu tworzę cte które wyciąga mi pojedyncze id userów, nie ma sensu wykonywać kilka razy tego samego podzapytania:

with cteUSR as (
select distinct
	usr
from
	tabela1
)
select
	*
from (
	Select
		usr
		,(select N'' + kontakt from tabela1 c where c.usr=cteUSR.usr order by rn for xml path(N'')) Sekwencja
	from
		cteUSR) dt
where
	Sekwencja like '%TTT%'
	or sekwencja like '%NNN%'

Wynik:

usr sekwencja
12345 TTNTTTNN
0

Najlepiej byłoby w jednym zapytaniu. Wyniki zapisywane są chronologicznie, czyli jest kolumna z datą i godziną.

Edit: nie wiem dlaczego dopiero po zamieszczeniu przeze mnie odpowiedzi pojawił się Twój kolejny post (odświeżałem stronę). Dzięki za pomoc. Jutro rano sprawdzę to u siebie.

0

Dzięki wielkie za pomoc Panczo. Twoje rozwiązanie działa w 100% do tego dowiedziałem się paru nowych rzeczy :)

Pozdrawiam.

1
select * from
(
select *
,lag(kontakt) over(partition by usr order by rn) kontakt2
,lag(kontakt,2) over(partition by usr order by rn) kontakt3
from tabela
) x
 where kontakt = kontakt2
 and kontakt = kontakt3 

1 użytkowników online, w tym zalogowanych: 0, gości: 1