oracle count query with union - sql

I have a query with union all functionality each giving me count(*) return from respective queries and another count query like below. I want an outer query that gives the total.
1st query
select count(*) from a
union all
select count(*) from b;
Sample result for 1st query:
COUNT
10
40
2nd query
select count(*) from xy;
Sample result for 2nd query:
COUNT
20
I want output like this in 2 rows:
TABLES
COUNT
xy
20
ab
50
something like above. How can I achieve this in oracle? please suggest the best way to do this.
I wrote a select and union all but not sure how to proceed further.

One option is to sum counts returned by the 1st query and then union it with the 2nd; also, add constants which show the source:
select 'ab' what, (select count(*) from a) + (select count(*) from b) cnt from dual
union all
select 'xy', count(*) from xy;

You can use:
SELECT 'ab' AS type,
COUNT(*) AS total
FROM ( SELECT 1 FROM a UNION ALL
SELECT 1 from b );
UNION ALL
SELECT 'xy', COUNT(*)
FROM xy;

You can sum counts from your three unioned Select statements and group the result by combination of sources:
WITH
a AS
( Select LEVEL "A_ID", 'some column a' "COL_A" From Dual Connect By LEVEL <= 30 ),
b AS
( Select LEVEL "B_ID", 'some column b' "COL_B" From Dual Connect By LEVEL <= 20 ),
xy AS
( Select LEVEL "XY_ID", 'some column xy' "COL_XY" From Dual Connect By LEVEL <= 20 )
with above sample data it is like here:
SELECT
CASE WHEN SOURCE IN('a', 'b') THEN 'ab' ELSE SOURCE END "SOURCE",
Sum(CNT) "CNT"
FROM
( Select 'a' "SOURCE", Count(*) "CNT" From a Union All
Select 'b', Count(*) From b Union All
Select 'xy', Count(*) From xy
)
GROUP BY
CASE WHEN SOURCE IN('a', 'b') THEN 'ab' ELSE SOURCE END
--
-- R e s u l t :
-- SOURCE CNT
-- ------ ----------
-- ab 50
-- xy 20

Assuming that your real queries can be a lot more complex, I take it as a given that we shall not try to change them and somehow merge or split them.
Your first query returns two rows. You want to get their sum, so you must aggregate the result and use SUM.
Below query uses CTEs (subqueries in the WITH clause) for your two queries, and then a query that gets this sum. It then uses these CTEs for the final UNION ALL query.
with query1 (cnt) as (select count(*) from a union all select count(*) from b)
, query2 (cnt) as (select count(*) from xy)
, sumquery1 (total) as (select sum(cnt) from query1)
select 'ab' as tables, total from sumquery1
union all
select 'xy' as tables, cnt from query2
order by tables desc;

Related

Oracle Select max where a certain key is matched

i'm working with oracle, plSql, i need to query a table and select the max id where a key is matched, now i have this query
select t.* from (
select distinct (TO_CHAR(I.DATE, 'YYMMDD') || I.AUTH_CODE || I.AMOUNT || I.CARD_NUMBER) as kies, I.SID as ids
from transactions I) t group by kies, ids order by ids desc;
It's displaying this data
If i remove the ID from the query, it displays the distinct keys (in the query i use the alias KIES because keys was in blue, so i thought it might be a reserved word)
How can i display the max id (last one inserted) for every different key without displaying all the data like in the first image??
greetings.
Do you just want aggregation?
select thekey, max(sid)
from (select t.*,
(TO_CHAR(t.DATE, 'YYMMDD') || t.AUTH_CODE || t.AMOUNT || t.CARD_NUMBER) as thekey,
t.SID
from transactions t
) t
group by thekey
order by max(ids) desc;
Since you haven't provided data in text format, its difficult to type such long numbers and recreated the data.
However I think you can simply use the MAX analytical function to achieve your results.
with data as (
select 1111 keys,1 id from dual
union
select 2222, 1 from dual
union
select 1111, 2 from dual
union
select 2222,3 from dual
union
select 9999, 1 from dual
union
select 1111, 5 from dual
)
select distinct keys, max(id) over( partition by (keys)) from data
This query returns -
KEYS MAX(ID)OVER(PARTITIONBY(KEYS))
1111 5
9999 1
2222 3

Move columns to rows

I need to add the third column to the first column (my desire is that the first column will include also the third column)
Current status:
Desired Results:
You want UNION ALL :
SELECT t.entity, t.activity
FROM table t
UNION ALL
SELECT t.entity2, t.activity2
FROM table t;
If you have a lot of data, you may not want to scan the table multiple times -- which is what union all does.
Instead:
select (case when n.n = 1 then entity
when n.n = 2 then entity_2
end) as entity,
(case when n.n = 1 then activity
when n.n = 2 then activity_2
end) as activity
from t cross join
(select 1 as n from dual union all
select 2 as n from dual
) n;
In Oracle 12C+, this is simplified using lateral joins:
select t.entity, s.activity
from t cross join lateral
(select t.entity, t.activity from dual union all
select t.entity_2, t.activity_2 from dual
) s;
select entity, activity from <table>
union all
select entity_2, activity_2 from <table>
in general:
select col1,col2 from table1
union all
select col3,col4 form table1;

How to sum two rows after count and union two tables

I am trying to count over two tables and by union to take the results. How can i take the SUM of the rows afterwards?
select count(PARTNER_ID) from Administrator.PARTNERS
union
select count(RECORD_ID) from Administrator.DELETED_RECORDS WHERE RECORD_BASE_TYPE = 'PARTNER'
use subquery
select sum(val)
from
(
select count(PARTNER_ID) as val from Administrator.PARTNERS
union all
select count(RECORD_ID) from Administrator.DELETED_RECORDS WHERE RECORD_BASE_TYPE = 'PARTNER'
)A

Return COUNT rows of two SELECT related by UNION

I want to return the number of rows with columns from two Tables related by UNION.
I wrote this query
SELECT(
(SELECT * FROM(
(SELECT
ID_COMPTE,
TITLE,
LINK,
DATE_CREAT,
DATE_MODIF,
'TF1' AS "TYPE_FICHIER",
case when DATE_MODIF is null then DATE_CREAT else DATE_MODIF end as LAST_UPDATE FROM FIRST_TABLE FFF where ID_COMPTE= 11111111)
UNION
(SELECT
ID_COMPTE,
TITLE,
LINK,
DATE_CREAT,
DATE_MODIF,
'TF2' AS "TYPE_FICHIER",
case when DATE_MODIF is null then DATE_CREAT else DATE_MODIF end as LAST_UPDATE FROM SECOND_TABLE SSS where ID_COMPTE= 11111111)
order by LAST_UPDATE desc
) parentSelect WHERE ROWNUM BETWEEN 0 AND 2)), count(firstSelect) FROM firstSelect;
The purpose is to return the the last two rows with the count of all the rows of Table 1 and Table 2.
The query without the count works fine it's just the count that cause problem, I don't know how to insert it.
I tried also to use count() for each SELECT and SUM in the parent SELECT but it doesn't work.
This concept should work for you. Basically you select the data you want in the with clause. Then in the main select, you select your data, and the count.
WITH
base AS
(
SELECT 'TEST1' DATA FROM DUAL
UNION ALL
SELECT 'TEST2' DATA FROM DUAL
UNION ALL
SELECT 'TEST3' DATA FROM DUAL
)
SELECT (SELECT COUNT(*) FROM base) AS KOUNT, base.*
FROM base
;
You can use #Temp ( TempTable ).
Insert or manupulate the rows in it which you want to have and finally return it from stored procedure.

multiple select in one query [Teradata]

I'm trying to do multiple select from diff tables and just have a result in one column.
SELECT COUNT(*) FROM tb1 union
SELECT COUNT(*) FROM tb2 union
SELECT COUNT(*) FROM tb3;
output should be like:
593643
18103600
0
Problem with this is that the result is being arranged on desc order.
Like below:
0
593643
18103600
I would want the result to be as I put the select statement.
Please advise. Btw, I'm using teradata.
Thank you.
SQL result sets are inherently unordered, unless you explicitly specify an order by clause. You can do this with a subquery:
select cnt
from ((SELECT COUNT(*) as cnt, 1 as ord FROM tb1)
union all
(SELECT COUNT(*), 2 FROM tb2)
union all
(SELECT COUNT(*), 3 FROM tb3)
) t
order by ord
If you want specific order, add ORDER BY clause. It would also be good to use UNION ALL so you always get 3 rows, even with duplicate results (two tables having the same number of rows):
SELECT 'tbl1' AS tablename, COUNT(*) AS cnt, 1 AS ord FROM tb1 UNION ALL
SELECT 'tbl2', COUNT(*), 2 FROM tb2 UNION ALL
SELECT 'tbl3', COUNT(*), 3 FROM tb3
ORDER BY ord ;