multiple select in one query [Teradata] - sql

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 ;

Related

Combining 3 Tables and Finding the Count for Fruit in SQL

I need to combine three tables and find the total count for fruit after combining the three tables using SQL. The name of the fruit columns in the three tables are pr16pnk.fruit, pr16puf.fruit, and pr16yag.fruit. I have successfully found the results when the tables are separated, but I am having trouble combining the results. Listed below is the code that I used. I also need help putting it in descending order.
SELECT pr16pnk.fruit, COUNT(*)
FROM pr16pnk
GROUP BY pr16pnk.fruit
UNION ALL
SELECT pr16puf.fruit, COUNT(*)
FROM pr16puf
GROUP BY pr16puf.fruit
UNION ALL
SELECT pr16yag.fruit, COUNT(*)
FROM pr16yag
GROUP BY pr16yag.fruit
Use aggregators and ORDER BY, query is as simple as below
SELECT sum(A.fruit ,B.fruit, C.fruit)
FROM pr16pnk A
pr16puf B'
pr16yag C
ORDER BY fruit desc;
Just use a subquery:
SELECT fruit, SUM(cnt)
FROM ((SELECT pr16pnk.fruit, COUNT(*) as cnt
FROM pr16pnk
GROUP BY pr16pnk.fruit
) UNION ALL
SELECT pr16puf.fruit, COUNT(*) as cnt
FROM pr16puf
GROUP BY pr16puf.fruit
) UNION ALL
(SELECT pr16yag.fruit, COUNT(*) as cnt
FROM pr16yag
GROUP BY pr16yag.fruit
)
) f
GROUP BY fruit
Try this,
select f.fruit, count(*) from
(
SELECT pr16pnk.fruit from pr16pnk
union
SELECT pr16puf.fruit from pr16puf
union
SELECT pr16yag.fruit from pr16yag
) f
group by f.fruit
order by f.fruit desc

SQL - Find Record count for multiple tables at a time in snowflake

I want to see counts have Tables at 1 time, instead of Running each.
For EX:
select COUNT(*) from "Fact_MASTER ";
select COUNT(*) from "Dim_MASTER ";
select COUNT(*) from "Fact2 ";
select COUNT(*) from "Dim2";
select COUNT(*) from "Fact3";
select COUNT(*) from "Dim3"
Is there any way we can write a CTE to pull as Record count for each in a temp table or so like below:
You can use union all:
select 'Fact_MASTER', COUNT(*) from "Fact_MASTER " union all
select 'Dim_MASTER', COUNT(*) from "Dim_MASTER " union all
select 'Fact2', COUNT(*) from "Fact2 " union all
select 'Dim2', COUNT(*) from "Dim2" union all
select 'Fact3', COUNT(*) from "Fact3" union all
select 'Dim3', COUNT(*) from "Dim3"
It looks like you want each count in a separate column. If so, you can turn each query to a separate subquery, and select them:
select
(select count(*) from "Fact_MASTER") as fact_master,
(select count(*) from "Dim_MASTER ") as dim_master,
(select count(*) from "Fact2") as fact2,
(select count(*) from "Dim2") as dim2,
(select count(*) from "Fact3") as fact3
(select count(*) from "Dim3") as dim3
Have you tried simply running:
SHOW TABLES;
If you then want to use that information for something else, you can then follow-up with something like:
select "rows" as cnt
from table(result_scan(last_query_id()))
where "name" in (...);
If you have a set list of tables that you want to PIVOT you can also use the result_scan() function to pivot the data:
https://docs.snowflake.com/en/sql-reference/constructs/pivot.html

SQL Union displaying wrong result

SELECT COUNT(id)
FROM table1
UNION
SELECT COUNT(id)
FROM table2
UNION
SELECT COUNT(id)
FROM table3
Result is
247811
58599
76
But actually
table1 has 247811 rows
table2 has 76 rows
table3 has 58599 rows
The union operator makes no gaurantees about the order. If you want to order the results in a particular way, you'd have to do so explicitly, with an order by clause. Note also that union removes duplicates, so you'd better use union all. E.g.:
SELECT cnt
FROM (SELECT 't1', COUNT(id) FROM table1
UNION ALL
SELECT 't2', COUNT(id) FROM table2
UNION ALL
SELECT 't3', COUNT(id) FROM table3) t
ORDER BY 1 ASC
if your problem depends on order by please order by your select after union, if you have a problem with count?(in your example there is a different count 79 and 76) it depends on that you use count(id) it is not same is count(*), count(id) ignores every null in Id column, count(*) it is count of your table rows

How to use order by with union all in sql?

I tried the sql query given below:
SELECT * FROM (SELECT *
FROM TABLE_A ORDER BY COLUMN_1)DUMMY_TABLE
UNION ALL
SELECT * FROM TABLE_B
It results in the following error:
The ORDER BY clause is invalid in views, inline functions, derived
tables, subqueries, and common table expressions, unless TOP or FOR
XML is also specified.
I need to use order by in union all. How do I accomplish this?
SELECT *
FROM
(
SELECT * FROM TABLE_A
UNION ALL
SELECT * FROM TABLE_B
) dum
-- ORDER BY .....
but if you want to have all records from Table_A on the top of the result list, the you can add user define value which you can use for ordering,
SELECT *
FROM
(
SELECT *, 1 sortby FROM TABLE_A
UNION ALL
SELECT *, 2 sortby FROM TABLE_B
) dum
ORDER BY sortby
You don't really need to have parenthesis. You can sort directly:
SELECT *, 1 AS RN FROM TABLE_A
UNION ALL
SELECT *, 2 AS RN FROM TABLE_B
ORDER BY RN, COLUMN_1
Not an OP direct response, but I thought I would jimmy in here responding to the the OP's ERROR messsage, which may point you in another direction entirely!
All these answers are referring to an overall ORDER BY once the record set has been retrieved and you sort the lot.
What if you want to ORDER BY each portion of the UNION independantly, and still have them "joined" in the same SELECT?
SELECT pass1.* FROM
(SELECT TOP 1000 tblA.ID, tblA.CustomerName
FROM TABLE_A AS tblA ORDER BY 2) AS pass1
UNION ALL
SELECT pass2.* FROM
(SELECT TOP 1000 tblB.ID, tblB.CustomerName
FROM TABLE_B AS tblB ORDER BY 2) AS pass2
Note the TOP 1000 is an arbitary number. Use a big enough number to capture all of the data you require.
There will be times when you need to do something like this :
Pull top 5 from table 1 based on a sort
and bottom 5 from table 2 based on another sort
and union these together.
solution
select * from (
-- top 5 records
select top 5 col1, col2, col3
from table1
group by col1, col2
order by col3 desc ) z
union all
select * from (
-- bottom 5 records
select top 5 col1, col2, col3
from table2
group by col1, col2
order by col3 ) z
this was the only way i was able to get around the error and worked fine for me.
SELECT * FROM (SELECT *
FROM TABLE_A ORDER BY COLUMN_1)DUMMY_TABLE
UNION ALL
SELECT * FROM TABLE_B
ORDER BY 2;
2 is column number here .. In Oracle SQL you can use the column number by which you want to sort the data
This solved my SELECT statement:
SELECT * FROM
(SELECT id,name FROM TABLE_A
UNION ALL
SELECT id,name FROM TABLE_B ) dum
order by dum.id , dum.name
where id and name columns available in tables and you can use your columns .
Simply use that , no need parenthesis or anything else
SELECT *, id as TABLE_A_ID FROM TABLE_A
UNION ALL
SELECT *, id as TABLE_B_ID FROM TABLE_B
ORDER BY TABLE_A_ID, TABLE_B_ID
ORDER BY after the last UNION should apply to both datasets joined by union.
The solution shown below:
SELECT *,id AS sameColumn1 FROM Locations
UNION ALL
SELECT *,id AS sameColumn2 FROM Cities
ORDER BY sameColumn1,sameColumn2
select CONCAT(Name, '(',substr(occupation, 1, 1), ')') AS f1
from OCCUPATIONS
union
select temp.str AS f1 from
(select count(occupation) AS counts, occupation, concat('There are a total of ' ,count(occupation) ,' ', lower(occupation),'s.') As str from OCCUPATIONS group by occupation order by counts ASC, occupation ASC
) As temp
order by f1

Using different order by with union

I want to write a query like
select top 10 * from A
order by price
union
select top 3 * from A
order by price
or sth like that
select top 10 * from A
where name like '%smt%'
order by price
union
select top 3 * from A
where name not like '%smt%'
order by price
Can you please help me?
This should work:
SELECT *
FROM (SELECT TOP 10 A.*, 0 AS Ordinal
FROM A
ORDER BY [Price]) AS A1
UNION ALL
SELECT *
FROM (SELECT TOP 3 A.*, 1 AS Ordinal
FROM A
ORDER BY [Name]) AS A2
ORDER BY Ordinal
From MSDN:
In a query that uses UNION, EXCEPT, or INTERSECT operators, ORDER BY
is allowed only at the end of the statement. This restriction applies
only to when you specify UNION, EXCEPT and INTERSECT in a top-level
query and not in a subquery.
Edited: to force the order you need to apply an ORDER BY to the outer query. I've added a constant value column to both queries.
This is a real hacky way to do this. You probably want these as separate queries in reality, but this should give you the result you want...
select *
from (
select top 10 *, 1 as 'ord', price as 'ordprice' from A
union
select top 3 *, 2 as 'ord', 0 as 'ordprice' from A
) a
order by ord, ordprice, name
UNION doesn't like ORDER by clauses in the UNIONed expressions.
Try this:
SELECT * FROM
(SELECT TOP 10 * FROM A ORDER BY Price) SetA
UNION
SELECT * FROM
(SELECT TOP 3 * FROM a ORDER BY name) Setb
[ORDER BY something]
This spoofs the UNION operator into ignoring the ORDER BYs, which still operate correctly on the TOP operator.
You can apply a final ORDER BY to order the UNIONed set, if you like.
[No longer applies exactly to your question now that it's edited!]
select top 10 *,0 as RS from A
union
select top 3 *,1 as RS from A
order by
RS,
CASE WHEN RS=0 THEN price END, --Don't affect RS 1
name
cmd.CommandText = "SELECT 0 AS Employee_ID, 'No Employees' as Employee_FullName , 'id1' Orderkey
UNION ALL
SELECT Employee_ID, Employee_FullName, 'id2' Orderkey
FROM tblEmployee
ORDER BY Orderkey, Employee_FullName"
ds = dbconn.SelectQuery(cmd)
ds.Tables(0).Columns.Remove(ds.Tables(0).Columns("Orderkey"))