2016-12-09 1 views
1

J'ai recherché et trouvé des questions/réponses comme mon problème ici, mais rien que je puisse trouver exactement correspond.SQL - GROUP BY & HAVING COUNT numéro

SELECTING with multiple WHERE conditions on same column --- Ce lien est TRÈS proche mais ne fonctionne toujours pas pour mon problème.

Problème: J'ai une table qui abrite les méthodes de paiement et le statut de paiement (état vierge est OK)

SEL_PRO_PMTMETHOD_PK SEL_PROFILE_DETAIL_FK PMT_TYPE PMT_STATUS 
43827     342997     EFT   G 
43828     342997     EFT   P 
43829     342997     RCC 
43826     342997     EFT 

43776     342922     EFT 
43777     342922     EFT   G 
43778     342922     EFT   P 

Je dois développer la production unique en SEL_PROFILE_DETAIL_FK selon qu'il a que les entrées TEF, SEULEMENT RCC entrées, ou les deux entrées EFT et RCC.

j'ai compris les choses faciles pour seulement EFT et SEULEMENT RCC

Mais je dois être en mesure de dire s'il y a les deux entrées EFT et RCC dans le groupe FK.

Mon code à ce jour:

SELECT pmt_type 
FROM sel_pro_pmtmethod 
WHERE sel_profile_detail_fk = '342997'  
    AND pmt_type IN ('EFT', 'RCC') 
GROUP BY pmt_type 
HAVING COUNT(distinct pmt_type) >= 1 

Ce code est de retour en arrière pour les deux pmt_type ensembles de données ci-dessus. Peu importe si elle a à la fois EFT et RCC, ou seulement l'EFT.

J'ai changé la clause HAVING COUNT être « = 2 », mais qui ne retourne rien parce que le nombre de CCOS = 1 et les TEF = 3.

Mais ce que j'ai besoin est pour ce WHERE/GROUP BY/Avoir le scénario vrai est s'il y a une entrée EFT ET RCC dans le groupement. Si un est manquant alors il échoue.

+0

'PRESENTANT COUNT (distinct pmt_type) = 2' à donner les résultats désirés car DISTINCT ne comptera qu'une occurrence de chaque valeur, de sorte qu'il ne comptera qu'une seule fois «EFT» et «RCC» une fois.Oh et 'GROUP BY SEL_PROFILE_DETAIL_FK' ne sont pas' pmt_type' – Matt

+0

On dirait que vous avez été fermé en utilisant HAVING COUNT = 2, cette partie que vous pouvez changer en une simple requête, mais seulement 2 colonnes SEL_PROFILE_DETAIL_FK et PMT_TYPE. Regrouper seulement par SEL_PROFILE_DETAIL_FK mais dans où clause mettre pmt_type IN ('EFT', 'RCC'). Non Avoir est requis. Utilisez-le comme sous-requête et joignez/joignez-vous à n'importe quelle requête avec ses SEL_PROFILE_DETAIL_FK – Girish

+0

EFT et RCC sont-ils les ** seuls ** types de paiement? S'il peut y avoir plus de deux types de paiement, et que vous êtes uniquement intéressé par ces deux types, vous pouvez modifier les deux réponses fournies (qui sont correctes s'il n'y a que deux types de paiement) - la clause HAVING peut être modifiée comme 'having count (cas où pmt_type = 'EFT' puis 'x' end)> 0 et count (cas où pmt_type = 'RCC' puis 'x' fin)> 0'. – mathguy

Répondre

2
SELECT SEL_PROFILE_DETAIL_FK 
FROM sel_pro_pmtmethod 
WHERE pmt_type IN ('EFT', 'RCC') 
GROUP BY SEL_PROFILE_DETAIL_FK 
HAVING COUNT(distinct pmt_type) = 2 

Votre groupe en a eu tort. grouper par pmt_type signifiera qu'il montrera seulement 1 type par rangée. Parce que vous le voulez par la clé étrangère, vous devez grouper par là.

DISTINCT signifie qu'il ne comptera qu'une seule occurrence de chaque valeur.

Et si vous voulez vraiment tous les documents connexes, vous pouvez utiliser fonctions de fenêtre et agrégation conditionnelle:

SELECT * 
FROM 
    (
     SELECT 
      * 
      ,COUNT(CASE WHEN PMT_TYPE = 'EFT' THEN PMT_TYPE END) OVER (PARTITION BY SEL_PROFILE_DETAIL_FK) EftCount 
      ,COUNT(CASE WHEN PMT_TYPE = 'RCC' THEN PMT_TYPE END) OVER (PARTITION BY SEL_PROFILE_DETAIL_FK) RCCCount 
     FROM 
      sel_pro_pmtmethod 
     WHERE 
      PMT_TYPE IN ('EFT','RCC') 
    ) t 
WHERE 
    t.EftCount > 0 
    AND t.RCCCount > 0 

Ou une autre alternative pour obtenir tous les documents originaux est de prendre la première méthode et utiliser EXISTS dans une sous requête corrélative comme ceci:

SELECT * 
FROM 
    sel_pro_pmtmethod m1 
WHERE 
    EXISTS (SELECT 1 
      FROM sel_pro_pmtmethod m2 
      WHERE 
      m1.SEL_PROFILE_DETAIL_FK = m2.SEL_PROFILE_DETAIL_FK 
      m2.pmt_type IN ('EFT', 'RCC') 
      GROUP BY m2.SEL_PROFILE_DETAIL_FK 
      HAVING COUNT(distinct m2.pmt_type) = 2 

et pour répondre à cette partie de votre poste « Je dois développer sortie unique par SEL_PROFILE_DETAIL_FK selon qu'elle a UNIQUEMENT des entrées EFT, SEULEMENT des entrées RCC ou des entrées EFT et RCC. " Il fait sonner comme vous ne voulez pas réellement limiter à seulement quand ils sont à la fois, mais savoir si l'un ou l'autre ou les deux est présente et vous pouvez le faire avec conditional aggregation comme ceci:

SELECT 
    SEL_PROFILE_DETAIL_FK 
    ,CASE 
     WHEN EFTCount > 0 AND RCCCount > 0 THEN 'Both' 
     WHEN RCCCount > 0 THEN 'RCC' 
     ELSE 'EFT' 
    END as PmtTypesPresent 

FROM 
    (
    SELECT 
     SEL_PROFILE_DETAIL_FK 
     ,COUNT(CASE WHEN PMT_TYPE = 'EFT' THEN PMT_TYPE END) as EFTCount 
     ,COUNT(CASE WHEN PMT_TYPE = 'RCC' THEN PMT_TYPE END) as RCCCount 
    FROM sel_pro_pmtmethod 
    WHERE pmt_type IN ('EFT', 'RCC') 
    GROUP BY SEL_PROFILE_DETAIL_FK 
) t 
+0

Extrêmement utile. Je vous remercie! –

+0

@MarkLudlow votre accueil. Si vous avez obtenu une réponse dont vous aviez besoin, veuillez en accepter une que vous avez utilisée afin que les autres sachent que vous avez pris soin de vous, et que des points de réputation sont attribués. En outre, les réponses/réponses correctes que vous avez utilisées sont bonnes. à votre santé. – Matt

2

Essayez ceci:

SELECT SEL_PROFILE_DETAIL_FK 
FROM sel_pro_pmtmethod 
WHERE pmt_type IN ('EFT', 'RCC') 
GROUP BY SEL_PROFILE_DETAIL_FK 
HAVING MIN(pmt_type) <> MAX(pmt_type) 
+0

+ 1 cette méthode fonctionne aussi parce qu'elle est groupée correctement et compare que les MAX et MIN ne sont pas du même type – Matt