简体   繁体   中英

Oracle: How do I join two result set queries (based on the same table) and then subtract the results?

My problem

I have two queries that have the same select and from criteria but have a different where statement. Each query counts the number of 'actions'. The first query counts all files created, while the other query counts all files that have been deleted. To get the updated file count, I need to join them and then subtract the result set count for deleted from the result set count for created.

Here are my two queries. They are essentially the same except for one of them has table2.auditid = 15 for created and the other has table2.auditid = 14 for deleted.

Created:

SELECT decode(table1.id,
2984, 'Category 1',
3298, 'Category 2',
2390, 'Category 3',
4039, 'Category 4',
5048, 'Category 5',
'Unknown') "Category",
COUNT (table1.id) AS "Files Created"
FROM table1
JOIN
maintable ON maintable.dataid = table1.id
JOIN 
table2 ON table2.dataid = maintable.id
JOIN
table3 ON table3.id = table2.userid
WHERE table2.auditid = 15
AND auditdate >= %1
AND table2.subtype = 0
AND table1.subtype = -18
GROUP BY table1.id

Deleted:

SELECT decode(table1.id,
2984, 'Category 1',
3298, 'Category 2',
2390, 'Category 3',
4039, 'Category 4',
5048, 'Category 5',
'Unknown') "Category",
COUNT (table1.id) AS "Files Created"
FROM table1
JOIN
maintable ON maintable.dataid = table1.id
JOIN 
table2 ON table2.dataid = maintable.id
JOIN
table3 ON table3.id = table2.userid
WHERE table2.auditid = 14
AND auditdate >= %1
AND table2.subtype = 0
AND table1.subtype = -18
GROUP BY table1.id

Note that these queries run well on their own.


What I've Tried

  • I can't use the minus statement as it doesn't work for result sets (I forgot about this and had asked this question previously)
  • I've tried to nest these two queries as subqueries and use union, etc. but could not get it to work.
  • I've tried the method described in ( SQL sum 2 different column by different condtion then subtraction and add ). This gave me error ORA-00904 String Invalid Identifier "table1.id.

Here's the code I adapted:

select decode(table1.id,
2984, 'Category 1',
3298, 'Category 2',
2390, 'Category 3',
4039, 'Category 4',
5048, 'Category 5',
'Unknown') "Category", 
(filescreated.CNT - filesdeleted.CNT) as "Final Count", 
from (
 SELECT table1.id, 
 COUNT(table1.id) as CNT
 FROM table1
 JOIN
 maintable ON maintable.dataid = table1.id
 JOIN 
 table2 ON table2.dataid = maintable.id
 JOIN
 table3 ON table3.id = table2.userid
 WHERE table2.auditid = 15
 AND auditdate >= %1
 AND table2.subtype = 0
 AND table1.subtype = -18
 GROUP BY table1.id) filescreated,
    (SELECT table1.id,
    COUNT(llattrdata.defid) as CNT
    FROM table1
    JOIN
    maintable ON maintable.dataid = table1.id
    JOIN 
    table2 ON table2.dataid = maintable.id
    JOIN
    table3 ON table3.id = table2.userid
    WHERE table2.auditid = 14
    AND auditdate >= %1
    AND table2.subtype = 0
    AND table1.subtype = -18
    GROUP BY table1.id) filesdeleted

ORDER BY table1.id

Can anyone provide some insight ?

In your "Deleted" query block you are still giving the column name "Files Created" in the SELECT list; I assume that is a mistake, it should be "Files Deleted" , right?

To answer your question: It appears that you recognize files that are "created" vs. "deleted" by the table2.auditid attribute, correct? 15 for created, 14 for deleted?

To capture both in a single query, that part of the last group of where conditions should become

... where table2.auditid in (14, 15)  and   ...

Then you only need to change the aggregate function in the outer select - it needs to be a sum , and a conditional sum at that.

count(table1.id) counts non-null values. I assume the id can't be null, so that is the same as count(*) - or, even, sum(1) . This will help with the current assignment: what you need instead of sum(1) when you want to add 1 for each table2.auditid = 15 but subtract 1 for each table2.auditid = 14 is:

sum(decode(table2.auditid, 15, +1, 14, -1))   [as <whatever>]

Good luck!

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