1

I have the below design of my tables:-


Table A 
--------------------------
subCatId | catId | catDesc
--------------------------
   1     |  3    |  100
   2     |  3    |  100
   3     |  5    |  100
   4     |  5    |  100
   5     |       |  100

Table B
--------------------------
subCatId | amount 
--------------------------
   1     |  10
   2     |  20
   3     |   5
   4     |  15
   5     |    

Third table, i.e. Table AB, is the one where the records are to be inserted. On the basis of the above tables the query should: 1. check Table AB, whether any subCatId exists in it or not. 2. if the table is empty then get all the subCatId & catId present in Table A which has catDesc=100 and based on Table A's subCatId take Table B's amount.


Table AB
--------------------------
subCatId | catId | amount
--------------------------
   1     |  3    |  10
   2     |  3    |  20
   3     |  5    |  35       
   4     |  5    |  15
   5     |       |  50       

As you can see above in Table AB for subCatId 1 & 2 the catId is 3 so the amount values for 1 & 2 should sum up and show up for subCatId 3 (including the amount value 5 which was already there in Table B). Similary, for subCatId 5 the amount value should sum up from the subCatId 3 & 4.

I will really appreciate if someone can help me on getting the expected result as shown above for TableAB.

I have tried the below query separately

SELECT A.CATID, SUM(B.AMOUNT) 
FROM A LEFT OUTER JOIN B 
           ON A.SUBCATID = B.SUBCATID 
WHERE A.CATDESC=100
  AND A.SUBCATID NOT IN 
          (SELECT AB.SUBCATID FROM AB) 
GROUP BY CATID;

However, it only gives catid and the total amount values but I could not find a way to get the subCatId and their respective amounts also. Please help...thanks. The reason for applying left outer join is that, if a subCatId does not exist in Table B, but it exists in Table A then it should also be shown with the results.

4

1 に答える 1

1

This explanation comes close, but doesn't quite get what you want.

First, start with the base table of amounts:

select a.subcatid, a.catid, b.amount
from (select *
      from A
      where a.catdesc = 100
     ) A left outer join
     B
     on a.subcatid = b.subcatid left outer join
     AB
     on a.subcatid = ab.subcatid and a.catid = b.catid
where ab.subcatid is null

Next, you want to take the amount here and add in all the amounts from where the catid equals the subcat id. To do this, we need a self join. I'll use the with syntax to define this as an alias:

with t as (
     select a.subcatid, a.catid, b.amount
     from (select *
           from A
           where a.catdesc = 100
          ) A left outer join
          B
          on a.subcatid = b.subcatid left outer join
          AB
          on a.subcatid = ab.subcatid and a.catid = b.catid
     where ab.subcatid is null
)
select t.subcatid, t.catid,
       (t.amount + coalesce(tcat.amount, 0)) as amount
from t left outer join
     (select catid, sum(amount) as amount
      from t
      group by catid
     ) tcat
     on t.subcatid = t.cat

The problem is that this sums the base amounts, but not the intermediate totals along the way. So, the total for "5" includes the base for "3" and "4", but not the subtotals beneath them.

To get the full solution, it seems like you will need one of two things. Either build a loop to go through the table row by row, using update and queries to get what you need. Or, I think Oracle has the "connect by" statement, which allows queries along tree structures. Unfortunately, I don't know it well enough to produce the correct SQL. Alternatively, if the tree structure is not too deep -- such as in your example -- then you can traverse one or two levels manually, if that is enough.

于 2012-07-07T21:44:22.380 に答える