SQL Error 10249 Hive with subqueries in SELECT clause - hive

I am trying to write query like
select (select count(1) from tableA), (select count(1) from tableB)
in Hive and there came an error
10249 SubQuery expressions are only allowed as where and having clause.
I think the grammar is right, is there any suggestion about this? Thank you!

Some support of queries in the select was added in Hive >= 2.3, see this Jira HIVE-16091 and docs: Subqueries in SELECT
If your Hive version does not support such subqueries in the select (and docs says such subqueries are not supported yet), move subqueries to the FROM and use CROSS JOIN or use UNION ALL + aggregation.
Using CROSS JOIN:
select a.cnt as count_a, b.cnt as count_b
from
(select count(1) as cnt from tableA) a
cross join
(select count(1) as cnt from tableB) b
Using UNION ALL + aggregation
select count(case when src='A' then 1 else NULL end) count_a,
count(case when src='B' then 1 else NULL end) count_b
from
(
select 'A' as src from tableA
union all
select 'B' as src from tableB
)s

Related

SQL Query to sum multiple count union queries

I have a statement with following structure, and I'm trying to sum all the count results.
I have tried using the SUM function outside of the nested count queries combined using the same variable declaration for each of the union, but error says that I must give them separate aliases. However, if I do that, won't I need to refer to these separately within the SUM function?
My SQL Code returning 2 rows:
SELECT COUNT(col_x) FROM tablea
UNION
SELECT COUNT(col_y) FROM tableb;
OUTPUT
64
10
Now when I try to SUM the answers I run into trouble:
WITH total as(
SELECT COUNT(col_x) FROM tablea as rowtotal
UNION
SELECT COUNT(col_y) FROM tableb as rowtotal
) SELECT SUM(rowtotal) from total;
The error is around using the variable 'rowtotal' twice. Surely there's an easier way to this?
I simply want a sum of both values as:
OUTPUT
74
You don't need window functions for that
select sum(cnt) as total
from
(
SELECT COUNT(col_x) as cnt FROM tablea
UNION
SELECT COUNT(col_y) FROM tableb
) tmp
You can use +:
SELECT ( (SELECT COUNT(col_x) FROM tablea) +
(SELECT COUNT(col_y) FROM tableb)
)
Or a cross join:
SELECT a_cnt + b_cnt
FROM (SELECT COUNT(col_x) as a_cnt FROM tablea) a CROSS JOIN
(SELECT COUNT(col_y) as b_cnt FROM tableb) b;
Do not use UNION! It removes duplicates, so your sum may be off. You can use UNION ALL, but you have alternatives.
Try this
WITH total as(
SELECT COUNT(col_x) as rowtotal FROM tablea
UNION
SELECT COUNT(col_y) FROM tableb
) SELECT SUM(rowtotal) from total
You don;t need to give alias on table, instead it is actually saying to provide alias for column name.
WITH total as(
SELECT COUNT(col_x) as total FROM tablea --- it is necessary over here
UNION
SELECT COUNT(col_y) as total FROM tableb --- it is not mandatory to give alias on second statement of UNION
) SELECT SUM(rowtotal) as total from total;

TSQL Count Case When In

I am having trouble with some logic here. Trying to get a count of rows where S.ID's not in my subquery.
COUNT(CASE WHEN S.ID IN
(SELECT DISTINCT S.ID FROM...)
THEN 1 ELSE 0 END)
I am recieving the error:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
How to fix this or an alternative?
Maybe something like this?
SELECT COUNT(*) FROM .... WHERE ID NOT IN (SELECT DISTINCT ID FROM ...)
Using EXISTS :
SELECT COUNT(t.*) FROM table1 t WHERE NOT EXISTS (SELECT * FROM table2 WHERE ID = t.ID)
Use following construct with CTE.
with cte as
(
select
case
when S.ID in (SELECT DISTINCT S.ID FROM LookupTable) then 1
else 0
end
as SID
from MyTable)
select count(SID) as SIDCOUNT from cte;

Can i have one row in select from other table than currently referred ?

Say i have 2 tables "A" and "B", my query is as follows.
Select
count( a."col_A1") as ACount,
Sum(a."col_A2") as ASum,
(Select count(b."col_B1") from B b) as BCount
From A a
I'm not able to execute above statement in Oracle but it works fine in MSSQL.
Can any one help me ?
It's a valid construct, to include a subquery in an aggregation result, but it looks peculiar to me.
I'd construct it as:
select
a.c_col1,
a.s_col2,
b.c_col3
from
(select count(col1) c_col1,
sum(col2) s_col2
from table_a) a,
(select count(col3) c_col3
from table_b) b
Just add a GROUP BY 1 to the end of the query.
Select count( a."col_A1") as ACount
, sum(a."col_A2") as ASum
, (Select count(b."col_B1") from B b) as BCount
From A a
GROUP BY 1

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 ;

Custom order after distinct statements

I want to make a custom order: IN, OUT, FINISHED.
If I left case statement I am getting in FINISHED, IN, OUT.
I found this solution but it does not work for me - I am getting error.
select distinct 'IN' as STATUS,
(select count(*) ...)
from table
UNION ALL
select distinct 'OUT',
(select count(*) ...)
from table
UNION ALL
select distinct 'FINISHED',
(select count(*) ...)
from table
order by
case STATUS
when 'IN' then 1
when 'OUT' then 2
when 'FINISHED' then 3
end
The query that you provided has some syntax irregularities. I think the following solves your problem:
select *
from ((select distinct 'IN' as statusA, (select count(*) ...
from table
)
union all
(select distinct 'OUT', (select count(*) ...)
from table
)
union all
(select distinct 'FINISHED', (select count(*) ...)
from table
)
) t
order by status,
(case STATUSA when 'IN' then 1
when 'OUT' then 2
when 'FINISHED' then 3
end)
Your original problem could have several causes. You were missing the 'IN' in the first subquery. You are missing the comma after status in the order by. And, some databases apply the final order by in a series of unions to only the last query (although I think DB2 does this correctly).