web-dev-qa-db-fra.com

SQL Server 2008: TOP 10 et distincts ensemble

Comme le titre l'indique, j'utilise SQL Server 2008. Toutes mes excuses pour cette question si élémentaire. Je n'utilise SQL que depuis quelques jours. En ce moment, j'ai la requête suivante:

SELECT TOP 10 p.id, pl.nm, pl.val, pl.txt_val

from dm.labs pl
join mas_data.patients p    
  on pl.id = p.id
  where pl.nm like '%LDL%'
  and val is not null

Ce que je veux faire est d'utiliser select n avec des valeurs distinctes dans la colonne id. Rechercher dans certains forums dit utiliser

SELECT DISTINCT TOP 10 ...

mais quand je remplace la première ligne avec

SELECT DISTINCT TOP 10 p.id, pl.nm, pl.val, pl.txt_val

J'obtiens les mêmes résultats que sans le mot distinct. Que devrais-je faire pour filtrer uniquement les entrées d'identifiant en double?

Je vous remercie.

44
raoulcousins

L'option facile consiste à utiliser group by et à sélectionner min/max pour tous les autres champs.

SELECT TOP 10 
    p.id, 
    max(pl.nm),
    max(pl.val),
    max(pl.txt_val)
from 
    dm.labs pl
join 
    mas_data.patients p    
on 
    pl.id = p.id
  where 
    pl.nm like '%LDL%'
and 
    val is not null
group by 
    p.id

Cela peut être assez fastidieux pour une table large, l’autre option est d’utiliser le classement par-dessus

SELECT TOP 10 
    p.id, 
     pl.nm, 
     pl.val, 
   pl.txt_val, 
    rank() over(partition by p.id order by p.id) as Rank
from 
    dm.labs pl
join 
    mas_data.patients p    
on 
    pl.id = p.id
  where 
    pl.nm like '%LDL%'
and 
    val is not null
and
    Rank = 1
10
Paul Creasey

Essayer

SELECT distinct TOP 10 MyId FROM sometable
115
Halim
select top 10 p.id from(select distinct p.id  from tablename)tablename
26
Vaishnavi Kumar

Peu d'idées:

  1. Vous avez plusieurs champs dans votre instruction select. Toute valeur différente de l'autre rendra cette ligne distincte.
  2. Les clauses TOP sont généralement associées aux clauses WHERE. Sinon, TOP ne veut pas dire grand chose. Top de quoi? La manière dont vous spécifiez "top of what" consiste à trier en utilisant WHERE
  3. Il est tout à fait possible d'obtenir les mêmes résultats même si vous utilisez TOP et DISTINCT et WHERE. Assurez-vous que les données que vous interrogez peuvent effectivement être filtrées et classées comme vous le souhaitez.

Essayez quelque chose comme ça:

SELECT DISTINCT TOP 10 p.id, pl.nm -- , pl.val, pl.txt_val
FROM dm.labs pl
JOIN mas_data.patients p    
on pl.id = p.id
where pl.nm like '%LDL%'
and val is not null
ORDER BY pl.nm

Notez que j'ai commenté certaines des commandes SELECT pour limiter votre jeu de résultats et la logique DISTINCT.

4
Paul Sasik
select top 10 * from
(
    select distinct p.id, ....
)

marchera.

3
cdonner

Je sais que ce fil est vieux, mais je me suis dit que je voudrais ajouter ce qui a été dit depuis que je viens de rencontrer le même problème Ce n'est peut-être pas efficace, mais je pense que le travail est fait.

SELECT TOP 10 p.id, pl.nm, pl.val, pl.txt_val
INTO #yourTempTable
from dm.labs pl 
join mas_data.patients p on pl.id = p.id   
where pl.nm like '%LDL%' and val is not null

select p.id, pl.nm, pl.val, pl.txt_val
from #yourTempTable
where id IN (select distinct id from #yourTempTable)
2
Jeff

eh bien je ne m'y serais pas attendu, mais celui de Halim CHOISIS distincte TOP 10 MyId DE sometable

est fonctionnellement identique à celui de Vaishnavi Kumar sélectionnez les 10 meilleurs identifiants de (nom distinct du nom du fichier) 

create table #names ([name] varchar(10))
insert into #names ([name]) values ('jim')
insert into #names ([name]) values ('jim')
insert into #names ([name]) values ('bob')
insert into #names ([name]) values ('mary')
insert into #names ([name]) values ('bob')
insert into #names ([name]) values ('mary')
insert into #names ([name]) values ('john')
insert into #names ([name]) values ('mark')
insert into #names ([name]) values ('matthew')
insert into #names ([name]) values ('luke')
insert into #names ([name]) values ('peter')

select distinct top 5 [name] from #names

select top 5 * from (select distinct [name] from #names) subquery 

drop table #names

produit les mêmes résultats pour les deux sélections:

    name
1   bob
2   jim
3   john
4   luke
5   mark

il est curieux que le choix du top 5 distinct ne soit pas valide, mais le choix du top 5 distinct fonctionne correctement.

2
user5292841
SELECT TOP 14 A, B, C
  FROM MyDatabase
  Where EXISTS 
   (
     Select Distinct[A] FROM MyDatabase
    )
0
SQLServer

DISTINCT supprime les lignes si toutes les valeurs sélectionnées sont égales. Apparemment, vous avez des entrées avec le même p.id mais avec différents pl.nm (ou pl.val ou pl.txt_val). La réponse à votre question dépend de l’une de ces valeurs que vous voulez afficher dans la ligne one avec votre p.id (le premier? Le plus petit? Aucun?).

0
Heinzi

Je pense que le problème est que vous voulez un résultat pour chaque p.id?

Mais vous obtenez des résultats "en double" pour certains IDs, est-ce exact?

Le mot clé DISTINCT s’applique à l’ensemble des résultats, donc à pl.nm, pl.val, pl.txt_val et pas seulement p.id.

Vous avez besoin de quelque chose comme 

SELECT TOP 10 p.id, max( p1.nm ), max (p1.val), ...
FROM ...
GROUP BY p.id

Vous n'aurez pas besoin du mot clé distinct alors.

0
MikeW

C'est la bonne réponse et vous pouvez trouver 3 valeurs de hauteur du tableau

SELECT TOP(1)  T.id FROM (SELECT DISTINCT TOP(3) st.id  FROM Table1 AS t1 , Table2 AS t2 WHERE t1.id=t2.id ORDER BY (t2.id) DESC ) T ORDER BY(T.id) ASC
0
Hafiz Asad

Vous pouvez utiliser une expression de table commune pour obtenir les 10 principaux identifiants distincts, puis les associer au reste de vos données:

;WITH TopTenIDs AS
( 
   SELECT DISTINCT TOP 10 id
   FROM dm.labs 
   ORDER BY ......
)
SELECT 
    tti.id, pl.nm, pl.val, pl.txt_val
FROM
    TopTenIDs tti
INNER JOIN
    dm.labs pl ON pl.id = tti.id
INNER JOIN 
    mas_data.patients p ON pl.id = p.id
WHERE
    pl.nm like '%LDL%'
    AND val IS NOT NULL

Cela devrait fonctionner. Notez bien que si vous avez une clause "TOP x", vous avez généralement aussi besoin d'une clause ORDER BY - si vous souhaitez utiliser le TOP 10, vous devez indiquer au système dans quel ordre se trouve "TOP".

PS: pourquoi rejoignez-vous même le tableau "patients", si vous n'en sélectionnez aucun champ ??

0
marc_s