SQL select语句返回在同一ID上多次发生一组事件的记录

时间:2018-10-10 21:48:00

标签: sql sql-server ssms

说我有一张桌子:

CREATE TABLE births 
(
    childid INT,
    momid INT,
    eclampsia VARCHAR(1),
    preeclampsia VARCHAR(1),
    hypertension VARCHAR(1)
);

插入记录:

INSERT INTO BIRTHS (CHILDID, MOMID, ECLAMPSIA)
VALUES (654321, 123456, 'Y'),
       (654321, 123456, 'Y'),

INSERT INTO BIRTHS (CHILDID, MOMID, HYPERTENSION)
VALUES (987652, 465468, 'Y'),
       (987987, 465468, 'Y')

INSERT INTO BIRTHS (CHILDID, MOMID)
VALUES (687765, 465468)

INSERT INTO BIRTHS (CHILDID, MOMID, PREECLAMPSIA)
VALUES (649870, 846587, 'Y')

INSERT INTO BIRTHS (CHILDID, MOMID)
VALUES (787463, 846587);

我想返回所有生育一个以上孩子并且在一次以上怀孕中接受了这三种诊断之一的母亲的记录。

我的预期结果是:

 child    momid     eclampsia    preeclampsia    hypertension
 -------------------------------------------------------------
 654321   123456       Y
 431265   123456                     Y
 987652   465468                                     Y
 987987   465468                                     Y

我该怎么写呢?

我的草率查询不能完全满足我的要求。它可以在某种程度上起作用,但仍会给我提供记录,其中女仆仅对一次怀孕进行了诊断。

select distinct 
    a.*, b.eclampsia, b.preeclampsia, b.hypertension 
from 
    births a
join 
    births b on a.momid = b.momid
where 
    a.childid != b.childid 
    and a.eclampsia = 'y' 
    and (b.eclampsia = 'y' or b.preeclampsia = 'y' or b.hypertension = 'y') 
     or a.preeclampsia = 'y' 
    and (b.preeclampsia = 'y' or b.eclampsia = 'Y' or b.hypertension = 'y') 
     or a.hypertension = 'y' 
    and (b.hypertension = 'y' or b.eclampsia = 'y' or b.preeclampsia = 'y')
order by  
    mapersonid 

5 个答案:

答案 0 :(得分:1)

这是一种实现方式。它对出生表中的记录进行计数,这些记录显示每个母亲的症状之一,只要该计数> 1作为条件来显示记录,只要该记录还显示以下条件之一即可:

SELECT childid, momid, 
    COALESCE(eclampsia, '') AS eclampsia, 
    COALESCE(preeclampsia, '') AS preeclampsia, 
    COALESCE(hypertension, '') AS hypertension
FROM births b1
WHERE (SELECT COUNT(*) FROM births b2 WHERE b2.momid = b1.momid AND
      (ECLAMPSIA = 'Y' OR PREECLAMPSIA = 'Y' OR HYPERTENSION = 'Y')
       GROUP BY momid) > 1  AND
      (ECLAMPSIA = 'Y' OR PREECLAMPSIA = 'Y' OR HYPERTENSION = 'Y')

输出

 child    momid     eclampsia    preeclampsia    hypertension
 654321   123456       Y
 431265   123456                     Y
 987652   465468                                     Y
 987987   465468                                     Y

答案 1 :(得分:1)

首先使用CTECASE表达式获得每个妈妈的总并发症,然后将Momid上的CTE和Births表结合起来,然后过滤并发症多的妈妈。如下所示-

;WITH BirthCTE as(
Select momid,
    SUM(CASE WHEN ECLAMPSIA = 'Y' OR PREECLAMPSIA = 'Y' OR HYPERTENSION = 'Y' THEN 1 ELSE 0 END) As TotalComl
FROM births
GROUP BY momid
)
select b.* from births b
inner join BirthCTE cte on b.momid = cte.momid
Where TotalComl > 1 -- More than one complication
   and (ECLAMPSIA = 'Y' OR PREECLAMPSIA = 'Y' OR HYPERTENSION = 'Y') -- atleast one complication

答案 2 :(得分:1)

我将通过此查询解决您的问题:

SELECT * FROM births 
WHERE momid IN(
  SELECT momid FROM births GROUP BY momid
  HAVING COUNT(1) >1 AND
  SUM(CASE WHEN eclampsia = 'Y' THEN 1 WHEN preeclampsia = 'Y' THEN 1 WHEN hypertension = 'Y' THEN 1 ELSE 0 END) > 1) 
AND (eclampsia = 'Y' OR preeclampsia = 'Y' OR hypertension = 'Y')

基本上,您可以通过分组过滤momids并在HAVING子句中制定条件,然后使用momids的列表来构建所需的输出。

答案 3 :(得分:0)

这是错误的数据结构。您想要一张有 no 并发症的出生表。然后,您需要一个birthComplications表,每个并发症一行(如果有)。

您可以即时重组数据。然后聚合:

select b.momid
from births b outer apply
     (select v.complication
      from (values ('eclampsia', b.eclampsia), ('hypertension', b.hypertension), ('preeclampsia', b.preeclampsia)
           ) v(complication, flag)
      where flag = 'y'
     )
group by b.momid
having count(*) > 1 and -- more than one pregnancy
       count(distinct case when v.complication is not null then b.childid end) > 1;

实际上,您可以简化一次以上妊娠合并症的母亲的逻辑。看起来像:

select b.momid
from births b apply  -- only keep pregnancies with complications
     (select v.complication
      from (values ('eclampsia', b.eclampsia), ('hypertension', b.hypertension), ('preeclampsia', b.preeclampsia)
           ) v(complication, flag)
      where flag = 'y'
     )
group by b.momid
having count(distinct b.childid) > 1;

答案 4 :(得分:0)

尝试

select momid, count(*) as "children",
count(eclampsia) as "eclampsia",
count(preeclampsia) as "preeclampsia",
count(hypertension) as "hypertension"
from births
group by momid
having count(*) > 1 and
(
    count(eclampsia) > 1 or
    count(preeclampsia) > 1 or
    count(hypertension) > 1
);

您将得到类似的东西:

enter image description here