我有一个mating_history
表:
id cage_id code event_date animal_id
---------------------------------------------------------------
100 4163 FA 03-Aug-2016 10.51.55.000 AM 3570
101 4163 MA 03-Aug-2016 10.52.13.000 AM 2053
102 4163 MR 29-Aug-2016 10.23.24.000 AM 2053
103 4163 MA 11-Oct-2016 12.50.02.000 PM 5882
104 4163 MR 31-Oct-2016 01.37.28.000 PM 5882
105 4163 MA 07-Nov-2016 01.27.58.000 PM 5882
106 4163 FA 19-Apr-2017 11.46.50.000 AM 6011
107 4163 FA 19-Apr-2017 11.48.31.000 AM 6010
MA = Male added to cage
MR = Male removed from cage
FA = Female added to cage
FR = Female removed from cage
在上表中,第一行表示在event_date
上,为了繁殖,将一只雌性动物(id为3570
)添加到笼中。
如果你按照历史记录记录,你会得到这些点"实际交配" :
female_id male_id event_date
-----------------------------------------------------------------
3570 2053 03-Aug-2016 10.52.13.000 AM
3570 5882 11-Oct-2016 12.50.02.000 PM
3570 5882 07-Nov-2016 01.27.58.000 PM
6011 5882 19-Apr-2017 11.46.50.000 AM
6010 5882 19-Apr-2017 11.48.31.000 AM
然而,当我试图将我的想法转换为SQL时,我没有得到我想要的内容。
SELECT
be.cage_id, be.code AS base_code, be.animal_id AS base_animal, be.event_date AS base_date,
se.code AS sub_code, se.animal_id AS sub_animal, se.event_date AS sub_date
FROM mating_history be
LEFT JOIN mating_history se ON se.cage_id = be.cage_id
WHERE be.cage_id = 4163
AND be.code != se.code
AND be.code IN ('MA', 'FA')
AND se.code IN ('MA', 'FA')
AND be.event_date < se.event_date
ORDER BY be.event_date ASC, se.event_date ASC
cage_id base_code base_animal base_date sub_code sub_animal sub_date
--------------------------------------------------------------------------------------------------------------------
4163 FA 3570 03-Aug-2016 10.51.55.000 AM MA 2053 03-Aug-2016 10.52.13.000 AM
4163 FA 3570 03-Aug-2016 10.51.55.000 AM MA 5882 11-Oct-2016 12.50.02.000 PM
4163 FA 3570 03-Aug-2016 10.51.55.000 AM MA 5882 07-Nov-2016 01.27.58.000 PM
4163 MA 2053 03-Aug-2016 10.52.13.000 AM FA 6011 19-Apr-2017 11.46.50.000 AM --------> WRONG
4163 MA 2053 03-Aug-2016 10.52.13.000 AM FA 6010 19-Apr-2017 11.48.31.000 AM --------> WRONG
4163 MA 5882 11-Oct-2016 12.50.02.000 PM FA 6011 19-Apr-2017 11.46.50.000 AM --------> WRONG
4163 MA 5882 11-Oct-2016 12.50.02.000 PM FA 6010 19-Apr-2017 11.48.31.000 AM --------> WRONG
4163 MA 5882 07-Nov-2016 01.27.58.000 PM FA 6011 19-Apr-2017 11.46.50.000 AM
4163 MA 5882 07-Nov-2016 01.27.58.000 PM FA 6010 19-Apr-2017 11.48.31.000 AM
我没有关于如何获得我需要的5行的想法。如何进一步过滤结果,以便在这种情况下只得到我需要的5行?
可选:创建笛卡尔产品是否是我尝试完成的最佳解决方案?有更好的方法吗?
答案 0 :(得分:1)
这可能有效:
<强>设置强>:
create table mating_history (
id number primary key
, cage_id number not null
, code char(2) check (code in ('FA', 'FR', 'MA', 'MR'))
, event_date timestamp not null
, animal_id number not null
);
insert into mating_history
select 100, 4163, 'FA', timestamp '2016-08-03 10:51:55', 3570 from dual union all
select 101, 4163, 'MA', timestamp '2016-08-03 10:52:13', 2053 from dual union all
select 102, 4163, 'MR', timestamp '2016-08-29 10:23:24', 2053 from dual union all
select 103, 4163, 'MA', timestamp '2016-10-11 12:50:02', 5882 from dual union all
select 104, 4163, 'MR', timestamp '2016-10-31 13:37:28', 5882 from dual union all
select 105, 4163, 'MA', timestamp '2016-11-07 13:27:58', 5882 from dual union all
select 106, 4163, 'FA', timestamp '2017-04-19 11:46:50', 6011 from dual union all
select 107, 4163, 'FA', timestamp '2017-04-19 11:48:31', 6010 from dual
;
commit;
这在几个方面都很糟糕。笼子和动物应该有小的“尺寸”表。动物表应该显示性别(而不是当前表中的“代码”)。现在我假设数据与您提供的数据一样,并且您不倾向于修复数据模型。
<强>查询强>:
with
grouped ( cage_id, sex, event_code, event_date, animal_id, grp ) as (
select cage_id, substr(code, 1, 1), substr(code, 2),
event_date, animal_id,
row_number() over (partition by animal_id, code order by event_date)
from mating_history
),
pivoted as (
select *
from grouped
pivot ( max(event_date) for event_code in ('A' as a, 'R' as r) )
)
select f.animal_id as female_id,
m.animal_id as male_id,
greatest(f.a, m.a) as event_date
from ( select * from pivoted where sex = 'F' ) f
join
( select * from pivoted where sex = 'M' ) m
on f.cage_id = m.cage_id
and ( f.r >= m.a or f.r is null )
and ( m.r >= f.a or m.r is null )
order by event_date, female_id, male_id
;
输出 :( event_date
列使用我当前的NLS_TIMESTAMP_FORMAT
)
FEMALE_ID MALE_ID EVENT_DATE
--------- ------- ------------------------------
3570 2053 03-AUG-2016 10.52.13.000000000
3570 5882 11-OCT-2016 12.50.02.000000000
3570 5882 07-NOV-2016 13.27.58.000000000
6011 5882 19-APR-2017 11.46.50.000000000
6010 5882 19-APR-2017 11.48.31.000000000
答案 1 :(得分:0)
让我们跟踪谁在笼子里。 。 。并假设只有一个男性和一个女性。以下每次更换都会让笼中的动物进入:
tf.nn.dynamic_rnn
你想要两只动物都存在的那些:
select mh.*,
(case when 'MA' = lag(case when base_code in ('MA', 'MR') then base_code end ignore nulls) over (partition by cage_id order by event_date)
then lag(case when base_code in ('MA') then animal_id end ignore nulls) over (partition by cage_id order by event_date)
end) as male_animal,
(case when 'FA' = lag(case when base_code in ('FA', 'FR') then base_code end ignore nulls) over (partition by cage_id order by event_date)
then lag(case when base_code in ('FA') then animal_id end ignore nulls) over (partition by cage_id order by event_date)
end) as female_animal,
lead(event_date) over (partition by cage_id order by event_date) as next_event_date
from mating_history mh;