简体   繁体   中英

How to sum column values from two tables and preserve another column which is only in one table

i have created tables item and item2 , I know maybe it's data redundancy but i want to know how can select it, and create a view?

create table item(
id  number(10) primary key,
name varchar2(20),
mark number(10));
insert into item values(10,'Apple1',23);
insert into item values(11,'Apple2',0);
insert into item values(12,'Apple3',0);
insert into item values(13,'Apple4',0);
insert into item values(14,'Apple4',0);
insert into item values(15,'Apple4',0);
insert into item values(16,'Apple4',0);

create table  item2(
id number(10),
mark number(10));
alter table item2 add(constraint id_fk FOREIGN KEY (id) references  item(id));
Insert into  item2 values(10,1);
Insert into  item2 values(10,1);
Insert into  item2 values(11,7);
Insert into  item2 values(12,14);

I can query both:

select * from item;

ID  Name    Mark
10  Apple1    23
11  Apple2     0
12  Apple3     0
13  Apple4     0
14  Apple4     0
15  Apple4     0
16  Apple4     0

select * from item2;

ID  Mark
10     1
10     1
11     7
12    14

I want to get the result set below using the select statement sum from the item and item2 tables:

ID  Name    Mark
10  Apple1    25
11  Apple2     7
12  Apple3    14
13  Apple4     0
14  Apple4     0
15  Apple4     0
16  Apple4     0

How can I combine my queries to produce that output?

If I understand this correctly, you want to "pretend" that the second table had the NAME column also, populated according to the first table; then you would want to GROUP BY id and get the sum of MARK .

If so, instead of joining the tables to get the names (either before or after combining the tables and computing the sums), you can use a UNION ALL , in which you insert a fake NAME column with NULL in it for the second table; then you group by id , you sum the MARK column, and you take the MAX over NAME . MAX ignores NULL , so it will just pick the name from table ITEM .

The solution below follows that logic in every detail.

select   id, max(name) as name, sum(mark) as mark
from     ( select id, name, mark
             from item
           union all
           select id, null as name, mark
             from item2
         )
group by id
;

You can union the two tables together on the id and mark. The name you can either add a null name column into the union and do a max/min on that field to get one value from that table. Otherwise you can union the id and marks, and then join back to the original table with the name to grab it from there and include it in the group by.

select item_table.id, item_table.name, sum(mark_data_set.mark) as mark_score
from
(select 
    id, mark 
from item
union all
select id, mark
from item2
) mark_data_set
inner join item item_table on (mark_data_set.id = item_table.id)
group by item_table.id, item_table.name

How about this?

select  id,name,(m1 +nvl(m2,0)) mark
from
(select t1.id,t1.name,t1.mark m1,t2.mark m2
from
item t1 
LEFT OUTER JOIN
(select id,sum(mark) mark from item2
group by id) t2
ON
t2.id = t1.id
)
order by id;

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM