0
votes

Sélectionnez sans doublons à moins d'être interrompu par d'autres valeurs

Compte tenu des données suivantes:

name | temp
-----------
hoi  | 15 // selected
hoi  | 15 // ignored duplicate
hoi  | 15 // ignored duplicate
hoi  | 16 // selected
hoi  | 15 // selected because while not being unique it follows a different value
hoi  | 15 // ignored duplicate
hej  | 13 // selected
hoi  | 13 // selected
hoi  | 13 // ignored duplicate
hoi  | 14 // selected
hoi  | 13 // selected because while not being unique it follows a different value


5 commentaires

Comment les archives sont-elles commandées? Existe-t-il un champ d'identification ou un champ de date qui peut être utilisé pour commander ces enregistrements?


@rohitvats Il y a en effet un champ d'identification et un champ de date!


C'est un problème de lacunes et de îles. Les solutions ont tendance à différer de DMBS, et vous n'avez pas marqué un, donc je ne peux donc pas offrir une solution spécifique à vos besoins. Une recherche rapide de Les lacunes et les îles , ainsi que votre SGBD doit vous libérer dans la bonne direction.


@Peterverleg Quelle version de mysql?


@Garethd 5.7 :-)


5 Réponses :


1
votes

Si vous utilisez Oracle:

select name, temp from (
     select id,
            name, 
            temp, 
            lag(temp,1,-99999) over (order by id) as temp_prev
       from table 
      order by id) t
 where t.temp != t.temp_prev


0 commentaires

2
votes

Solution générique

Vous pouvez utiliser la requête suivante pour le faire sur n'importe quel SGMS: xxx

SQL violon : http://sqlfiddle.com/#!9/0584ca3/9


2 commentaires

Cela ne fonctionne que si la colonne ID ne contient aucune lacune du tout.


@Garethd Fair Point, j'ai modifié la réponse pour gérer ce cas aussi. Merci d'avoir souligné.



2
votes

Étant donné que vous utilisez MySQL 5.7, qui ne prend pas en charge les fonctions analytiques, vous devez utiliser des variables pour stocker les valeurs de Temp et nom, à partir de la ligne précédente:

SELECT  MIN(ID) AS FirstID,
        t.Name,
        t.Temp,
        COUNT(*) AS Records,
        MAX(ID) AS LastID
FROM    (   SELECT  t.*,
                    ROW_NUMBER() OVER(ORDER BY ID) - 
                        ROW_NUMBER() OVER(PARTITION BY Temp, Name ORDER BY ID) AS GroupID
        FROM    YourTable AS t
        ORDER BY t.ID
        ) AS t
GROUP BY t.GroupID, t.Name, t.Temp
ORDER BY t.GroupID;


0 commentaires

1
votes
create table #temp (name varchar(3),temp int)
insert into #temp values ('hoi',15)
insert into #temp values ('hoi',15)
insert into #temp values ('hoi',15)
insert into #temp values ('hoi',16)
insert into #temp values ('hoi',15)
insert into #temp values ('hoi',15)
insert into #temp values ('hej',13)
insert into #temp values ('hoi',13)
insert into #temp values ('hoi',13)
insert into #temp values ('hoi',14)
insert into #temp values ('hoi',13)


;with FinalResult as (
select ROW_NUMBER()Over(partition by name,temp order by name) RowNumber,* 
from #temp
) 

select * from FinalResult where RowNumber =1
drop table #temp

0 commentaires

1
votes

Vous voulez regarder la ligne précédente afin de décider de montrer une ligne ou non. Ce serait facile avec Lag code>, disponible à partir de MySQL 8. avec MySQL 5.7 Vous avez besoin d'une sous-requête corrélée avec limite code> plutôt pour obtenir la ligne précédente.

select *
from mytable
where not (name, temp) <=>
(
  select prev.name, prev.temp
  from mytable prev
  where prev.id < mytable.id
  order by prev.id desc
  limit 1
);


0 commentaires