2016-12-09 144 views
1

我已经研究和发现像我这里的问题这里的问题/答案,但没有我能找到完全适合。SQL - GROUP BY&HAVING COUNT问题

SELECTING with multiple WHERE conditions on same column ---此链接非常接近,但仍然不适合我的问题。

问题: 我有房子付款方式和付款状况的表(空白状态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 

我需要开发由SEL_PROFILE_DETAIL_FK唯一的输出取决于它是否有ONLY EFT的条目,ONLY RCC条目或EFT和RCC条目。

我想通了,只EFT和ONLY RCC

简单的东西,但我需要能够告诉如果有在FK分组BOTH EFT和RCC项目。

我迄今为止代码:

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 

此代码返回回pmt_type上面两组数据。无论它有EFT和RCC还是EFT都没关系。

我已经改变了HAVING子句COUNT为“= 2”,但不返回任何内容,因为农村信用社的数量= 1和EFT的= 3

但我需要的是这个WHERE/GROUP BY /如果在分组中存在EFT和RCC条目,则HAVING情况为真。如果有人失踪,则失败。

+0

'HAVING COUNT(不同的pmt_type)= 2'来产生你想要的结果,因为“DISTINCT”只会计算每个值的出现次数,因此它只会计算一次“EFT”和“RCC”一次。哦,'GROUP BY SEL_PROFILE_DETAIL_FK'不是'pmt_type' – Matt

+0

看起来你在使用HAVING COUNT = 2时是关闭的,那部分你可以改成一个简单的查询但只有2列SEL_PROFILE_DETAIL_FK和PMT_TYPE。按SEL_PROFILE_DETAIL_FK分组,但在where子句中放入pmt_type IN('EFT','RCC')。没有必要。将其用作子查询并使用其SEL_PROFILE_DETAIL_FK附加/加入任何查询 – Girish

+0

电子转帐和RCC是仅限**付款类型吗?如果可能有两种以上的付款类型,而您只对这两种付款感兴趣,则可以修改迄今为止提供的两个答案(如果只能有两种付款方式,这两种付款方式都是正确的) - HAVING子句可以更改为某种(如pmt_type ='EFT',则'x'结束)> 0并计数(当pmt_type ='RCC'时,则'x'结束)> 0'。 – mathguy

回答

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 

你按错了。按pmt_type分组将意味着它将只显示每行1个类型。因为你需要按外键来分组,所以你需要按外键分组。

DISTINCT将意味着它将只计数每个值的出现次数。

而且,如果你真的希望所有的相关的,你可以使用窗口功能条件聚集记录:

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 

或者另一种选择让所有的原始记录是采取第一种方法并使用EXISTS在相关子查询,像这样:

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 

,并解决您的文章的这部分“我需要开发SEL_PROFILE_DETAIL_FK的唯一输出取决于它是否只有EFT条目,只有RCC条目或BOTH EFT和RCC条目。“这使得它听起来像你其实并不想限制到只有当他们都知道,但如果有一个或另一个或两者是存在,你可以做到这一点conditional aggregation像这样:

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

非常有帮助。谢谢! –

+0

@MarkLudlow您的欢迎。如果你已经得到了你需要的答案,请接受你使用过的其中一个答案,以便其他人知道你已经得到照顾,并授予声誉点。你也可以使用任何正确的答案/答案,以及良好的礼仪。干杯。 – Matt

2

试试这个:

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此方法也适用,因为它是正确分组的,并比较了最大和最小值不同的类型 – Matt