Remarque: J'ai une requête de travail, mais je recherche des optimisations pour l'utiliser sur de grandes tables.ignorer des lignes consécutives après une valeur spécifique
Supposons que j'ai une table comme ceci:
id session_id value
1 5 7
2 5 1
3 5 1
4 5 12
5 5 1
6 5 1
7 5 1
8 6 7
9 6 1
10 6 3
11 6 1
12 7 7
13 8 1
14 8 2
15 8 3
Je veux que les id de toutes les lignes avec la valeur 1 à une exception près: groupes de saut à valeur 1 qui suivent directement une valeur 7 dans le même session_id.
Fondamentalement, je rechercherais les groupes de valeur 1 qui suivent directement une valeur 7, limitée par l'identificateur de session, et ignorons ces groupes. Je montre ensuite toutes les valeurs restantes 1 lignes.
La sortie souhaitée montrant de l'ID:
5
6
7
11
13
j'ai pris un peu d'inspiration de this post et a fini avec ce code:
declare @req_data table (
id int primary key identity,
session_id int,
value int
)
insert into @req_data(session_id, value) values (5, 7)
insert into @req_data(session_id, value) values (5, 1) -- preceded by value 7 in same session, should be ignored
insert into @req_data(session_id, value) values (5, 1) -- ignore this one too
insert into @req_data(session_id, value) values (5, 12)
insert into @req_data(session_id, value) values (5, 1) -- preceded by value != 7, show this
insert into @req_data(session_id, value) values (5, 1) -- show this too
insert into @req_data(session_id, value) values (5, 1) -- show this too
insert into @req_data(session_id, value) values (6, 7)
insert into @req_data(session_id, value) values (6, 1) -- preceded by value 7 in same session, should be ignored
insert into @req_data(session_id, value) values (6, 3)
insert into @req_data(session_id, value) values (6, 1) -- preceded by value != 7, show this
insert into @req_data(session_id, value) values (7, 7)
insert into @req_data(session_id, value) values (8, 1) -- new session_id, show this
insert into @req_data(session_id, value) values (8, 2)
insert into @req_data(session_id, value) values (8, 3)
select id
from (
select session_id, id, max(skip) over (partition by grp) as 'skip'
from (
select tWithGroups.*,
(row_number() over (partition by session_id order by id) - row_number() over (partition by value order by id)) as grp
from (
select session_id, id, value,
case
when lag(value) over (partition by session_id order by session_id) = 7
then 1
else 0
end as 'skip'
from @req_data
) as tWithGroups
) as tWithSkipField
where tWithSkipField.value = 1
) as tYetAnotherOutput
where skip != 1
order by id
Cela donne le résultat souhaité, mais avec 4 blocs de sélection I pense que c'est trop inefficace pour utiliser sur de grandes tables.
Existe-t-il un moyen plus propre et plus rapide de faire cela?
Jetez un oeil à LAG: https://docs.microsoft.com/en-us/sql/t-sql/functions/lag-transact-sql Vous pouvez regarder la ligne précédente. – Leonidas199x
Ils ont utilisé 'LAG' dans la requête originale @ Leonidas199x – scsimon
Je pense que cela appartient à la révision de code, pas Stack Exchange. C'est le code de travail. –