Considérez ci-dessous le tableau tbl:
id date
1 2016
1 2017
2 2017
2 2017
3 2016
3 2017
4 2018
5 2018
Comment puis-je obtenir uniquement des lignes avec le même identifiant mais une date différente.
Pour le moment, je ne peux obtenir que des identifiants avec plus d'un compte comme ceci:
select id, date
from tbl
group by id
having count(id)>1
Comment puis-je obtenir uniquement les identifiants 1 et 3 avec la date?
Utilisez une fonction AGGREGATE
comme MIN
ou MAX
.
Si vous ne voulez qu'un seul enregistrement par ID, vous devez choisir la date souhaitée. Le premier (MIN) ou le dernier (MAX).
^^ Les informations ci-dessus ne correspondent pas à ce qui a été demandé.
Modifié par clarification dans les commentaires: utilisez simplement HAVING pour identifier les valeurs d'ID qui ont plus d'une date, puis appliquez-les à un nouveau SELECT.
SELECT id, Date
FROM tbl
WHERE id IN
(
select id
from tbl
group by id
having count(distinct date)>1
)
Quelques autres façons d'obtenir le même résultat:
Premièrement, en utilisant min(date) < max(date)
comme condition HAVING
- au lieu de count(distinct date) > 1
. Peut-être un peu plus efficace:
select id, date
from tbl
where id in
( select id
from tbl
group by id
having min(date) < max(date)
) ;
ou avec un JOIN
:
select t.id, t.date
from tbl as t
join
( select id
from tbl
group by id
having min(date) < max(date)
) as g
on g.id = t.id ;
et une conversion de la sous-requête IN
en une sous-requête EXISTS
corrélée. Bonus, nous pouvons supprimer le GROUP BY
:
select id, date
from tbl as t
where exists
( select 1
from tbl as t2
where t.id = t2.id
and t.date <> t2.date
) ;
Un autre qui utilise des fonctions de fenêtre:
select id, date
from
( select id, date,
diff_dates = case when min(date) over (partition by id)
< max(date) over (partition by id)
then 1
end
from tbl
) as d
where diff_dates = 1 ;
et enfin, un pour le concours d'obscurcissement:
select id, date from tbl
except
select id, min(date) from tbl group by id
intersect
select id, max(date) from tbl group by id ;
Testez dans dbfiffle.
Vous devez compter, comme vous l'avez fait, et compter séparément par date
SELECT T.id,T.date
FROM Table1 AS T
CROSS APPLY
(SELECT C.id
,Count(id) as count_id
,Count(Distinct date) as count_Distinct_Records
FROM Table1 AS C
WHERE C.id = T.id
GROUP BY id) AS CA
WHERE
CA.count_id > 1
AND count_Distinct_Records > 1
sortie ici:
id date
1 2016
1 2017
3 2016
3 2017