I have the following table. I want to sum the values present in rows by putting condition on dates.
Table - a
ID Entry_date weight height ID1 start_date end_date
111 2001-03-31 43 187
111 2001-04-30 23 165
111 2001-05-31 34 172 111 2001-04-30 2001-05-31
112 2001-06-30 54 183
112 2001-07-31 26 188 112 2001-06-30 2001-07-31
113 2001-04-30 23 165
113 2001-05-31 34 172 113 2001-04-30 2001-05-31
114 2001-05-31 46 177
114 2001-06-30 54 183
114 2001-07-31 26 188 114 2001-06-30 2001-07-31
If Entry_date >= start_date and Entry_date <= end_date
then it should sum weight and height for those entry_dates and ID. I don't know if i explained it right way or not. Resulting table should be like this:
Table -
ID Entry_date weight height ID1 start_date end_date
111 2001-03-31 43 187
111 2001-05-31 57 337 111 2001-04-30 2001-05-31
112 2001-07-31 80 371 112 2001-06-30 2001-07-31
113 2001-05-31 57 337 113 2001-04-30 2001-05-31
114 2001-05-31 46 177
114 2001-07-31 80 371 114 2001-06-30 2001-07-31
I tried following:
Select ID, Entry_date, sum(weight) as weight, sum(height) as height, ID1, start_date, end_date from table a
where Entry_date >= start_date and Entry_date <= end_date group by ID, Entry_date;
But it is not giving me desired result. It is giving me following results:
Table - a
ID Entry_date weight height ID1 start_date end_date
111 2001-05-31 34 172 111 2001-04-30 2001-05-31
112 2001-07-31 26 188 112 2001-06-30 2001-07-31
113 2001-05-31 34 172 113 2001-04-30 2001-05-31
114 2001-07-31 26 188 114 2001-06-30 2001-07-31
Can anyone please tell me how to proceed in this case?
This was a little complicated. Here's the query you could try:
select
id, entry_date,
(select sum(weight) from test
where entry_date between a.start_date and a.end_date
and id = a.id) as weight,
(select sum(height) from test
where entry_date between a.start_date and a.end_date
and id = a.id) as height,
id1, start_date, end_date
from test a
where start_date is not null and end_date is not null
union all
select a.*
from test a
left join test b
on a.id = b.id
where
(a.start_date is null and a.end_date is null)
and (b.start_date is not null and b.end_date is not null)
and not a.entry_date between b.start_date and b.end_date
order by id, entry_date
The query above the UNION ALL
clause will pull records that does math on weight and height. The query below the UNION ALL
clause only focuses on records that do not fall within the desired range and has null dates. You can tweak it to your comfort.
Example: http://sqlfiddle.com/#!9/f9b54a/6
Alternate method to query the same information
select e.id,
max(entry_date) as entry_date, sum(weight) as weight, sum(height) as height,
em.start_date, em.end_date
from test e
inner join (
select distinct id, start_date, end_date
from test
where start_date is not null and end_date is not null) em
on em.id = e.id
and e.entry_date between em.start_date and em.end_date
group by e.id, em.start_date, em.end_date
union all
select e.id, entry_date, weight, height, em.start_date, em.end_date
from test e
inner join (
select distinct id, start_date, end_date
from test
where start_date is not null and end_date is not null) em
on em.id = e.id
and not e.entry_date between em.start_date and em.end_date
order by id, entry_date
Example: http://sqlfiddle.com/#!9/f9b54a/8
Better method to store data
create table entrymaster (
id int,
start_date date,
end_date date
);
create table entries (
id int,
entry_date date,
weight int,
height int
);
select e.id,
max(entry_date) as entry_date, sum(weight) as weight, sum(height) as height,
em.start_date, em.end_date
from entries e
inner join entrymaster em
on em.id = e.id
and e.entry_date between em.start_date and em.end_date
group by e.id, em.start_date, em.end_date
union all
select e.id, entry_date, weight, height, em.start_date, em.end_date
from entries e
inner join entrymaster em
on em.id = e.id
and not e.entry_date between em.start_date and em.end_date
order by id, entry_date
Example: http://sqlfiddle.com/#!9/7eaaa/3
Select ID, Entry_date, sum(weight) as weight, sum(height) as height, ID1, start_date, end_date from table a
where Entry_date >= start_date and Entry_date <= end_date group by ID, Entry_date, ID1;
Added ID1 to the group by.
But this query may be not portable to some database engines, because you don't say to the server what value it should get from start_date and end_date if there is more than one line (first, min, max, etc).
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.