как проверить, имеет ли один из заявителей статус 0, и назначить статус претензии на основе этого

#sql #sql-server #tsql #sql-server-2012

#sql #sql-сервер #tsql #sql-server-2012

Вопрос:

У каждой претензии может быть несколько заявителей. Претензия рассматривается 'Open' , если хотя бы один из этих заявителей имеет ClaimantStatus = 0

Итак, мне нужно получить данные на уровне претензии (не заявителей) и создать столбец, ClaimStatus который указывал бы, является ли претензия Open или Closed .

Для каждого ClaimID мне нужно проверить, есть ли хотя бы у одного заявителя ClaimantStatus = 0 (открыто), и если это верно, то столбец ClaimStatus должен быть = 'Open' , в противном случае должен быть = 'Closed'

  declare @ClaimsTable table (ClaimID varchar(20))
 insert into @ClaimsTable values ('Claim1'),
                                 ('Claim2'),
                                 ('Claim3'),
                                 ('Claim4')

declare @ClaimantsTable table (ClaimID varchar(20),  ClaimantName varchar(50), ClaimantStatus int)
insert into @ClaimantsTable values ('Claim1','Claimant1',1),
                                   ('Claim1','Claimant2',0),
                                   ('Claim1','Claimant3',1),
                                   ('Claim2','Claimant2',0),
                                   ('Claim3','Claimant1',1),
                                   ('Claim3','Claimant2',1),
                                   ('Claim3','Claimant3',1),
                                   ('Claim4','Claimant1',0),
                                   ('Claim4','Claimant2',0)
--select * from @ClaimantsTable

select ClaimID,
        (select count (ClaimantName) from @ClaimantsTable ct where ct.ClaimID = c.ClaimID) as NumberOfClaimants,
    --below statement does not work correctly
        (select top 1 case when ClaimantStatus in (0) then 'Open' Else 'Closed' end as t from @ClaimantsTable ct where ct.ClaimID = c.ClaimID) as ClaimStatus
from @ClaimsTable c
  

Правильный ответ должен быть таким:

введите описание изображения здесь

Ответ №1:

Похоже, простого GROUP BY достаточно. Claim Открыт, если хотя бы у одного Claimant есть ClaimantStatus = 0, мы можем использовать MIN для определения этого. Здесь мы полагаемся на ClaimantStatus наличие только значений 0 и 1 .

 SELECT
    Claims.ClaimID
    ,COUNT(*) AS NumberOfClaimants
    ,CASE WHEN MIN(Claimants.ClaimantStatus) = 0 
        THEN 'Open' 
        ELSE 'Closed' 
    END AS ClaimStatus
FROM
    @ClaimsTable AS Claims
    INNER JOIN @ClaimantsTable AS Claimants ON Claimants.ClaimID = Claims.ClaimID
GROUP BY
    Claims.ClaimID
ORDER BY
    Claims.ClaimID;
  

Комментарии:

1. Отличный простой способ! Спасибо

Ответ №2:

Я думаю, что использование Exists — это то, что вы ищете

 select ClaimID,
    (select count (ClaimantName) from @ClaimantsTable ct where ct.ClaimID = c.ClaimID) as NumberOfClaimants,
    CASE WHEN EXISTS(SELECT 1 
                    FROM @ClaimantsTable AS claimant 
                    WHERE claimant.ClaimID = c.ClaimID
                        AND claimant.ClaimantStatus = 0) 
        THEN 'Open' 
        ELSE 'Closed' END AS claimStatus
from @ClaimsTable c
  

В зависимости от вашей ситуации вы также можете рассмотреть возможность сгруппированного запроса. Это может быть более эффективным, поскольку не нужно выполнять два отдельных поиска для подсчета и статуса. Для этого требуется, чтобы по каждой претензии был по крайней мере 1 заявитель.

 SELECT
    claim.ClaimId
    ,COUNT(*) AS NumberOfClaimants
    ,CASE WHEN SUM(CASE WHEN claimant.ClaimantStatus = 0 THEN 1 ELSE 0 END) > 0 THEN 'Open' ELSE 'Closed' END AS claimStatus
FROM
    @ClaimsTable AS claim
    INNER JOIN @ClaimantsTable AS claimant
        ON claim.ClaimID = claimant.ClaimID
GROUP BY
    claim.ClaimID
  

Комментарии:

1. Идеальный. Спасибо!