简体   繁体   中英

Counting Distinct rows based on column using SQL Server

I have 2 tables, A parent (table a) and a child (Table B). For each parent there can be multiple children (rows). What I need is if certain criteria is met in the children, I need it to count as 1.

Currently, my code is counting each child to the parent and it's not supposed to work that way. Here's my code simplified.

SELECT 
  cl.clientID, cl.code, cl.cName, 
  COUNT(case when e.errorCode NOT IN('DP','RB','WP','PE','OV') then c.rID end) as rateCount,
  SUM(case when e.errorCode NOT IN('DP','RB','WP','PE','OV') then e.refundDue else 0.0 end) as rateAmount,
  COUNT(case when e.errorCode IN('DP','RB','WP','PE','OV') then c.rID end) as paymentCount, 
  SUM(case when e.errorCode IN('DP','RB','WP','PE','OV') then e.refundDue else 0.0 end) as paymentAmount 

  FROM claims c 

  INNER JOIN clients cl ON cl.code=c.client 
  INNER JOIN entries e ON e.rID=c.rID 

  WHERE 

  status='closed' AND c.carrierID IN(3909) AND 
  (c.dateon >= '20170624' AND c.dateon < '20171220') 

  GROUP BY cl.clientID, cl.code, cl.cName ORDER BY cl.cName ASC

So, again, in the count statement, instead of counting 1 instance when the criteria is met, it's counting all the children. What connects the parent (claims) to child (entries) is the parents rID. I hope this is clear, but just to be sure,

Claims

rID   name
------------------
1     Damien
2     Jim

Entries

eID  rID  name
------------------
1    1    Yeye
2    1    Juju
3    1    Nao
4    1    Ty
5    2    Pai
6    2    Cha
7    2    Jac

So in this case, for Damien i should get a 1, as in yes, he has children and Jim should also get a 1.

Here's the results from the above SQL:

结果

Here are the tables:

载体表

客户表

索赔表

条目表

Seems like you're not really "counting", rather, you're setting a flag. This should get you what you're looking for:

SELECT 
  c.name 
  ,HasChild = CASE WHEN EXISTS (SELECT 1 FROM entries e WHERE e.rID = c.rID and e.errorCode NOT IN('DP','RB','WP','PE','OV')) THEN 1
                    ELSE 0
                    END    
FROM claims c

EDIT: Without sample data from each table, I can't really test this, but it appears that you may need to use COUNT(DISTINCT) . Try this:

SELECT
    cl.clientID
    ,cl.code
    ,cl.cName
    ,COUNT(DISTINCT CASE WHEN e.errorCode NOT IN ('DP', 'RB', 'WP', 'PE', 'OV') THEN
                    c.rID END
          )                                                                        AS rateCount
    ,SUM(CASE WHEN e.errorCode NOT IN ('DP', 'RB', 'WP', 'PE', 'OV') THEN
                  e.refundDue ELSE 0.0 END
        )                                                                          AS rateAmount
    ,COUNT(DISTINCT CASE WHEN e.errorCode IN ('DP', 'RB', 'WP', 'PE', 'OV') THEN c.rID END) AS paymentCount
    ,SUM(CASE WHEN e.errorCode IN ('DP', 'RB', 'WP', 'PE', 'OV') THEN
                  e.refundDue ELSE 0.0 END
        )                                                                          AS paymentAmount
FROM claims        c
INNER JOIN clients cl ON cl.code = c.client
INNER JOIN entries e ON e.rID = c.rID
WHERE status = 'closed'
    AND c.carrierID IN (3909)
    AND (c.dateon >= '20170624' AND c.dateon < '20171220')
GROUP BY cl.clientID
    ,cl.code
    ,cl.cName
ORDER BY cl.cName ASC;

With the help of subqueries you could try something like:

SELECT cl.clientID, cl.code, cl.cName,
case (select count(*) from entries e where e.rID=c.rID and e.errorCode
NOT IN('DP','RB','WP','PE','OV')) when 0 then 0 else 1 end  as rateCount 
FROM claims c 
    INNER JOIN clients cl ON cl.code=c.client 

GROUP BY cl.clientID, cl.code, cl.cName, rateCount  ORDER BY cl.cName ASC

ANOTHER APPROACH

Using common table expressions you can try something like:

WITH CTE AS (
select c.client, CASE count(*) WHEN 0 THEN 0 ELSE 1 END AS rateCount  
from entries e inner join claims c on c.rID = e.rID where e.errorCode
    NOT IN('DP','RB','WP','PE','OV') GROUP BY c.client
)   
SELECT cl.clientID, cl.code, cl.cName, coalesce( rateCount,0) as rateCount  
from CTE c right join clients cl on cl.code = c.client 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM