0
votes

Sélectionnez des lignes avec certaines combinaisons de conditions

J'ai une table d'opérations similaire à celle ci-dessous. Opérations soit réussir ou échouer. Parfois, l'opération n'est pas "essayée", une telle ligne n'existe pas: xxx

Comment puis-je trouver les identifiants des lignes de la table qui ont l'un ou l'autre L'opération B & C a échoué ou non essayé?

Pour l'exemple ci-dessus, le résultat souhaité est de 2 (échec de B), 3 (C échec du C), 4 (C non essayé), 5 (B non essayé), 6 (B & C pas essayé). , 7 (les deux B & C ont échoué)

sql

1 commentaires

Veuillez afficher votre code et indiquer où vous rencontrez des problèmes. La base de données que vous utilisez aiderait également.


6 Réponses :


0
votes

Utiliser l'agrégation

select id from tbale
group by id
having sum(case when Success='FALSE' then 1 else 0 end)>=1
or count(*)=2


3 commentaires

@Caiusjard c'est une agrégation simple, vous pouvez essayer dbfiddle.uk en créant une table Ça fonctionnera


Je sais comment ça marche; J'essaie de vous encourager pas seulement à résoudre le problème de l'OP, mais à l'expliquer (enseigner) pour son avantage et pour les futurs visiteurs.


@Caiusjard merci j'ai essayé d'expliquer et vous êtes invité à ajouter des notes qui aideront



1
votes

Ceci est délicat, car vous voulez que des lignes qui ne soient pas dans la table.

génère des combinaisons de tous les identifiants et opérations. Vous pouvez faire cela en utilisant un jointure cross code>. Puis filtrez ceux qui ont suivi: P>

select i.id, op.operation
from (select distinct id from operations) i cross join
     (select distinct operation from operations) op
where not exists (select 1
                  from operations o2
                  where o2.id = i.id and
                        o2.operation = i.operation and
                        o2.success = 'TRUE'
                 );


0 commentaires

0
votes

Je suppose que l'opération A est toujours présente: xxx

Essence Nous rompons vos données dans 3 tables virtuelles et que vous les joignez à ceux qui recherchent le faux ou le null créé par la jointure gauche lorsque les données n'existent pas. Cela nous permet également de déterminer pourquoi les choses ont mal tourné. Je n'étais pas sûr que les mots entre parenthèses étaient la production réelle que vous vouliez ou simplement expliquer pourquoi ce nombre devrait apparaître dans les résultats.

J'ai considéré que Gordon / Zaynul posté, mais pour moi, ce formulaire est plus auto-documentant / lisible. Vérifiez cependant les performances, car indexation de la colonne OPER peut aider considérablement.


0 commentaires

0
votes

Vous pouvez essayer ceci ... Veuillez trouver ce lien pour plus d'informations sur Exist lien xxx


1 commentaires

Ugh, ANSI-89 rejoint. Veuillez mettre à jour à ANSI-92 et expliquer également comment cela fonctionne



0
votes

Merci pour toutes les réponses. Avec l'inspiration des réponses et du café, mon cerveau a commencé à travailler et a proposé la solution que je ne peux pas croire que c'était aussi facile.

La solution, en mots, est à Sélectionner sinon (B & C a réussi ) code> p>

La sous-requête fait la partie "B & C réussie": P>

SELECT * FROM table WHERE id NOT IN (
   SELECT id FROM table 
   WHERE operation IN('B', 'C') AND success = true
   GROUP BY id HAVING COUNT(id) = 2
)


1 commentaires

Vous pouvez simplifier cela même furher et éviter la sous-requête: Sélectionnez ID à partir du groupe de table par ID ayant une somme (cas lors de la condition 1 autre 0 extrémité) <2 , mais cela pourrait échouer si (ID, Oper) est Pas unique.



0
votes

Une jointure croisée n'est pas requise ni prise en charge par tous les moteurs SQL, tels que MySQL. La première instruction SELECT sélectionne simplement des identifiants distincts où l'opération est soit «B», soit «C» et le succès est «faux». Mais nous devons ajouter ces identifiants que «B» ou «C» n'a jamais été tenté. Ceux-ci seraient des identifiants dans la table pour laquelle il n'y a aucune valeur de 'B' ou «C» dans la colonne Opération.

/* select all id's that have been tried but failed: */
SELECT DISTINCT id FROM operation
    WHERE operation IN ('B', 'C') AND success = 'FALSE'

UNION

/* select all id's that have never tried 'B': */
SELECT DISTINCT id FROM operation
    WHERE id NOT IN (
        SELECT DISTINCT id FROM operation
            WHERE operation = 'B'
    )

UNION

/* select all id's that have never tried 'C': */
SELECT DISTINCT id FROM operation
    WHERE id NOT IN (
        SELECT DISTINCT id FROM operation
            WHERE operation = 'C'
    )
;


0 commentaires