2017-08-16 1 views
-1

Je recherche une requête SQL pour résoudre le problème ci-dessous. J'ai le tableau suivant:Sélectionnez si le texte n'est pas vide ou s'il est vide puis la valeur de clé la plus élevée

Name | Description | RowNo 

A | emptyText | 1 
A | emptyText | 2 
A | xxx   | 3 
B | yyy   | 1 
C | emptyText | 1 
C | zzz   | 2 
D | emptyText | 1 

et je veux sélectionner les lignes où la description n'est pas emptyText ou s'il n'y a que emptyText pour un nom dans la description pour obtenir que la ligne avec la RowNo maximale. Ou si vous préférez les lignes qui ont la valeur RowNo maximale pour un nom donné sont les seules fois que je voudrais obtenir.

Pour l'exemple ci-dessus, je voudrais obtenir le résultat suivant:

Name | Description | RowNo 

A | xxx   | 3 
B | yyy   | 1 
C | zzz   | 2 
D | emptyText | 1 

Merci pour toute aide à l'avance!

+0

Plaques étiquette avec base de données (par ex. SQL Server/Oracle/MySQL, etc.) –

Répondre

2

Si nous supposons que le dernier numéro de ligne a le texte non vide et « EmptyText » est vraiment NULL, alors une simple agrégation fera:

select name, max(Description), max(RowNo) 
from t 
group by name; 

Si nous supposons que "EmptyText" n'est pas vraiment une chaîne mais NULL et qu'il n'y a qu'une seule ligne à retourner par Name, alors vous pouvez faire:

select name, max(Description) as Description, 
     coalesce(max(case when Description is not null then RowNo end), 
       max(RowNo) 
       ) as RowNo 
from t 
group by name; 

La réponse plus générale à votre question est:

select name, Description, Rowno 
from t 
where Description <> 'EmptyText' 
union all 
select name, max(Description), max(RowNo) 
from t 
where Description <> 'EmptyText' and 
     not exists (select 1 from t t2 where t2.Name = t.Name and t2.Descrdiption <> 'EmptyText'); 
+0

Merci beaucoup! En attendant, c'est ce que j'ai également découvert. Le texte vide n'était pas NULL mais un texte sans aucun caractère (''). Donc, l'agrégation a fait le travail! Merci beaucoup pour la réponse générale! – aragorn

-1

Vous pouvez essayer cette

SELECT DISTINCT Name, Description, MAX(RowNo) 
FROM table 
+0

La présence de 'MAX()' crée une clause implicite 'GROUP BY' qui produit une seule ligne de sortie. La requête est en fait invalide car les colonnes 'Name' et' Description' de la clause 'SELECT' n'apparaissent pas dans la clause' GROUP BY'. – axiac

1

Mettre en place des données d'échantillons (SQL Server):

select 'A' as Name, 'emptyText' as Description, 1 as RowNo into test union all 
select 'A' as Name, 'emptyText' as Description, 2 as RowNo union all 
select 'A' as Name, 'xxx' as Description, 3 as RowNo union all 
select 'B' as Name, 'yyy' as Description, 1 as RowNo union all 
select 'C' as Name, 'emptyText' as Description, 1 as RowNo union all 
select 'C' as Name, 'zzz' as Description, 2 as RowNo union all 
select 'D' as Name, 'emptyText' as Description, 1 as RowNo 

Utilisation first_value():

select distinct 
    a.Name 
    ,coalesce(first_value(nullif(Description, 'emptyText')) over (partition by Name order by RowNo desc), Description) as Description 
    ,first_value(RowNo) over (partition by Name order by RowNo desc) as RowNo 
from test a 

Résultat:

| Name | Description | RowNo | 
|------|-------------|-------| 
| A | xxx   | 3  | 
| B | yyy   | 1  | 
| C | zzz   | 2  | 
| D | emptyText | 1  | 
+0

Bien que je ne comprends pas pourquoi cela fonctionne probablement parce que je ne suis pas familier avec "coalesce". C'est une solution soignée :) Merci! – aragorn