2009-06-03 7 views
0

Pour une base de données d'accès qui ressemble à ceci: (Tous les champs de texte)accès Compliqué exclusion de requêtes SQL

 
Co1 Co2 Co3 Co4 
A k t N1 
B k t N2 
A m t N3 
B k z N4 
A k z N5 
C m t N6 
C k z N7 
C k t N8 
A k t N9 
C m t N10 

Je dois créer une sorte de rapports qui effectuer les tâches suivantes:

Les résultats doit sélectionner des lignes:

  1. ordonné par Co1 premier
  2. alors commandé par Co2
  3. uniquement les données où Co3 = t ou r
  4. quand Co3 est pas t ni r, alors toutes les autres lignes avec une C04 avant où de Co1 et Co2 étaient les mêmes que la ligne actuelle sont également exclus

1,2 et 3 sont extrêmement faciles à faire (Ordre par et Where respectivement), mais peut # 4 être fait dans l'accès SQL? Si ce n'est pas possible, je vais faire une petite application C# qui boucle les données, mais je pense que ce doit être possible de faire en SQL et si cela peut certainement être beaucoup mieux.

La requête et la base de données réelles sont plus compliquées, mais # 4 est où je suis bloqué.

Avec l'exemple que je donne le résultat serait:

 
A m t N3 
A k t N9 
C m t N6 
C m t N10 
C k t N8

Je crois que ce couvre tous les cas possibles.

Précision, nous utilisons la quatrième colonne (C4 dans cet exemple) pour déterminer l'ordre mais il s'agit d'un champ de texte avec des caractères et des chiffres. Le champ est une lettre suivie de 2 chiffres: A01, A02, .. A99, B01, etc ... Précision # 2, je ne suis pas à blâmer pour cette conception de base de données. : P

Donc, pour le gourou SQL parmi nous, cela peut-il être fait dans l'accès SQL? Comment?

Merci beaucoup pour toute aide que vous pouvez fournir.

+0

Je ne comprends pas votre contrainte # 4. Pourriez-vous le reformuler? "alors toutes les autres lignes avec un C04 antérieur" qu'est-ce que cela signifie? –

+0

@Unknown Google: Andomar était très correct quand il a amélioré le libellé de mon # 4 en l'inversant: nous devons exclure les lignes pour lesquelles il y a une ligne ultérieure où Co3 n'est pas t mais où la dernière rangée a le même Co1 et Co2 –

Répondre

0

Si je vous ai bien lu:

quand Co3 est pas t ni r, toutes autres lignes avec une C04 avant où Co1 ET Co2 étaient les mêmes que la ligne actuelle sont également exclus

Cela équivaut à exclure les lignes pour lesquelles une ligne ultérieure avec certaines conditions existe. Vous pouvez le faire avec une clause NOT EXISTS:

select * 
from YourTable cur 
where cur.Co3 in ('t','r') 
and not exists (
    select * 
    from YourTable later 
    where cur.Co1 = later.Co1 
    and cur.Co2 = later.Co2 
    and later.Co3 not in ('t','r') 
    and CInt(Mid(later.Co4,2)) > CInt(Mid(cur.Co4,2)) 
) 
order by cur.Co1, cur.Co2 desc, CInt(Mid(cur.Co4,2)) 

Maintenant, N10 n'est pas plus grand que N5 normalement. C'est à cela que sert le CInt (Mid (..., 2)): il transforme N10 en nombre 10 et le nombre N5 en 5.

+0

Merci beaucoup Andomar, j'ai dû le modifier un peu mais dans l'ensemble c'est exactement ce dont j'avais besoin. –

0

Une modification de la requête d'Andomar qui prend en compte les valeurs du départ Co4 avec des lettres différentes en utilisant la valeur ASCII du code de caractère pour déterminer l'ordre. Je suppose que la gamme est A01 ... A99, B01 ... B99 etc. et que B01 devrait être considéré "plus tard" que A99.

select * 
from Table1 cur 
where not exists (
    select 1 
    from Table1 later 
    where cur.Co1 = later.Co1 
    and cur.Co2 = later.Co2 
    and later.Co3 not in ('t','r') 
    and (asc(left(later.Co4,1)) * 100) + CInt(Mid(later.Co4,2)) > (asc(left(cur.Co4,1)) * 100) + CInt(Mid(cur.Co4,2)) 
) 
and cur.Co3 in ('t','r') 
order by cur.Co1, cur.Co2 
0

Ce n'est pas encore une réponse, mais un code de configuration pour les autres répondeurs.

create table #boost (
    Co1 char(1), 
    Co2 char(1), 
    Co3 char(1), 
    Co4 char(3) 
) 

insert into #boost values ('A', 'k', 't', 'N1') 
insert into #boost values ('B', 'k', 't', 'N2') 
insert into #boost values ('A', 'm', 't', 'N3') 
insert into #boost values ('B', 'k', 'z', 'N4') 
insert into #boost values ('A', 'k', 'z', 'N5') 
insert into #boost values ('C', 'm', 't', 'N6') 
insert into #boost values ('C', 'k', 'z', 'N7') 
insert into #boost values ('C', 'k', 't', 'N8') 
insert into #boost values ('A', 'k', 't', 'N9') 
insert into #boost values ('C', 'm', 't', 'N10') 
+0

Dans le cas où vous l'avez manqué, c'est une question de MS Access ;-) – Andomar

+0

Ce n'est même pas à distance valide Access SQL: D En outre, aurait dû être une édition de la publication originale. (Ou commenter si vous n'avez pas le représentant.) – Oorang