Оператор выбора SQL, который возвращает записи, в которых набор событий произошел более одного раза с одним и тем же идентификатором. - PullRequest
0 голосов
/ 11 октября 2018

Допустим, у меня есть таблица:

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 голосов
/ 11 октября 2018

Я бы решил вашу проблему с помощью этого запроса:

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построить желаемый вывод.

0 голосов
/ 11 октября 2018

попробуйте

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

0 голосов
/ 11 октября 2018

Это один из способов сделать это.Он подсчитывает записи в таблице рождений, которые отображают один из симптомов для каждой матери, используя это число> 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
0 голосов
/ 11 октября 2018

Сначала получите общее количество осложнений для каждой мамы, используя выражение CTE и CASE, затем объедините CTE с таблицей рождений на Momid, затем отфильтруйте мам, у которых есть более одного осложнения.Примерно так:

;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
0 голосов
/ 11 октября 2018

Это неправильная структура данных.Вы хотите таблицу рождений с без осложнений.Затем вам нужна таблица 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...