Postgres SQL: Do paging and total count rows in a union set. - sql

I have the following sql at the begnging.
select col1, col2 from table1
union
select col1, col2 from table2
Now I want to able to do a count the total number of rows in the union set from above, and order by col2. How should I do this?

with a as (
select col1, col2 from table1
union
select col1, col2 from table2
)
select *,count(1) over()
from a
order by col2
;

Related

Count(*) in SQL spanning multiple columns

I have a table similar to this
Can I get help writing up a query which will join col1, col2 & col3 and give me a result as below
I've spent an hour trying to figure it out with my mediocre skills and have got to some point.
select col1, count(*)
from tableName
group by col1
But I can't figure out how to join all three cols.
try this one
select
col,
count(*)
from
(select
id,
col1 as col
from
<table_name>
union all
select
id,
col2
from
<table_name>
union all
select
id,
col3
from
<table_name>)
group by
col
You need to group by col of the union of the 3 columns:
select t.col, count(*)
from (
select col1 col from tablename
union all
select col2 from tablename
union all
select col3 from tablename
) t
group by t.col
You should use UNION to group values from all columns to one column. After that, you can count values
SELECT
col,
count(*) as cnt
FROM
(SELECT col1 as col FROM table1
UNION ALL
SELECT col2 as col FROM table1
UNION ALL
SELECT col2 as col FROM table1) as t
GROUP BY col

How do I combine multiple tables into one new table? All of the columns headers are the same and in the same order

I have 12 tables in SQL Server with the exact same columns that I would like to combine into one brand new table. I don't want any data/rows deleted.
Thanks
Use union all:
insert into NewTable(col1, col2)
select col1, col2
from(
select col1, col2 from Table1
union all
select col1, col2 from Table2
union all
select col1, col2 from Table3
.....
)t
You can create new table while selecting like:
select col1, col2
into NewTable
from(
select col1, col2 from Table1
union all
select col1, col2 from Table2
union all
select col1, col2 from Table3
.....
)t

SQL Where Not Exists

I think I have a misunderstanding of how NOT EXISTS work and hope it can be clarified to me.
Here is the sample code I am running (also on SQL Fiddle)
select sum(col1) col1, sum(col2) col1, sum(col3) col3
from (
select 1 col1, 1 col2, 1 col3
from dual tbl1
)
where not exists(
select 2 col1, 1 col2, 1 col3
from dual tbl2
)
I thought that it should return:
1, 1, 1
But instead it returns nothing.
I make this assumption only on the fact that I though NOT EXISTS would give me a list of all the rows in the first query that do not exist in the second query (in this case 1,1,1)
Why does this not work
What would be the appropriate way to make it work the way I am expecting it to?
You are performing an uncorrelated subquery in your NOT EXISTS() condition. It always returns exactly one row, therefore the NOT EXISTS condition is never satisfied, and your query returns zero rows.
Oracle has a rowset difference operator, MINUS, that should do what you wanted:
select sum(col1) col1, sum(col2) col1, sum(col3) col3
from (
select 1 col1, 1 col2, 1 col3
from dual tbl1
MINUS
select 2 col1, 1 col2, 1 col3
from dual tbl2
)
SQL Server has an EXCEPT operator that does the same thing as Oracle's MINUS. Some other databases implement one or the other of these.
EXISTS just returns true if a record exists in the result set; it does not do any value checking. Since the sub-query returns one record, EXISTS is true, NOT EXISTS is false, and you get no records in your result.
Typically you have a WHERE cluase in the sub-query to compare values to the outer query.
One way to accomplish what you want is to use EXCEPT:
select sum(col1) col1, sum(col2) col1, sum(col3) col3
from (
select 1 col1, 1 col2, 1 col3
from dual tbl1
)
EXCEPT(
select 2 col1, 1 col2, 1 col3
from dual tbl2
)
A not exists that includes a select from dual will never return anything. Not exists will exclude rows where the embedded SQL returns something. Normally not exists should be used more like this:
select ... from MY_TABLE A where not exists (select 1 from OTHER_TABLE B where A.SOME_COL = B.SOME_COL)
As using NOT EXISTS is not good approach as it is return only single row so try it with MINUS or EXCEPT
select sum(col1) col1, sum(col2) col1, sum(col3) col3 from ( select 1 col1, 1 col2, 1 col3 from dual tbl1 MINUS select 2 col1, 1 col2, 1 col3 from dual tbl2 )
select sum(col1) col1, sum(col2) col1, sum(col3) col3 from ( select 1 col1, 1 col2, 1 col3 from dual tbl1 ) EXCEPT( select 2 col1, 1 col2, 1 col3 from dual tbl2 )

SQL query to simulate distinct

SELECT DISTINCT col1, col2 FROM table t ORDER BY col1;
This gives me distinct combination of col1 & col2. Is there an alternative way of writing the Oracle SQL query to get the unique combination of col1 & col2 records with out using the keyword distinct?
Use the UNIQUE keyword which is a synonym for DISTINCT:
SELECT UNIQUE col1, col2 FROM table t ORDER BY col1;
I don't see why you would want to but you could do
SELECT col1, col2 FROM table_t GROUP BY col1, col2 ORDER BY col1
Another - yet overly complex and somewhat useless - solution:
select *
from (
select col1,
col2,
row_number() over (partition by col1, col2 order by col1, col2) as rn
from the_table
)
where rn = 1
order by col1
select col1, col2
from table
group by col1, col2
order by col1
or a less elegant way:
select col1,col2 from table
UNION
select col1,col2 from table
order by col1;
or a even less elegant way:
select a.col1, a.col2
from (select col1, col2 from table
UNION
select NULL, NULL) a
where a.col1 is not null
order by a.col1
Yet another ...
select
col1,
col2
from
table t1
where
not exists (select *
from table t2
where t2.col1 = t1.col1 and
t2.col2 = t1.col2 and
t2.rowid > t1.rowid)
order by
col1;
Variations on the UNION solution by #aF. :
INTERSECT
SELECT col1, col2 FROM tableX
INTERSECT
SELECT col1, col2 FROM tableX
ORDER BY col1;
MINUS
SELECT col1, col2 FROM tableX
MINUS
SELECT col1, col2 FROM tableX WHERE 0 = 1
ORDER BY col1;
MINUS (2nd version, it will return one row less than the other versions, if there is (NULL, NULL) group)
SELECT col1, col2 FROM tableX
MINUS
SELECT NULL, NULL FROM dual
ORDER BY col1;
Another ...
select col1,
col2
from (
select col1,
col2,
rowid,
min(rowid) over (partition by col1, col2) min_rowid
from table)
where rowid = min_rowid
order by col1;

SQL query to select records from three Tables seperatly

SQL query which select the record from three tables and there is no relation between these tables. Actually I want to make it a VIEW.
suppose there are three tales Table1, Table2, Table3
I want to show records of Table1 first with some filter criteria
and then the records from Table2
and in last from Table3 as when we execute the view it show like the records like a Table.
There can be any number of rows but the records must be in this sequence.
I would suggest using UNION ALL instead of union if you want all the records from each of the tables. UNION will use a distinct to filter out duplicates. If you don't need tht it is just slowing down the query.
A further explanation here:
http://wiki.lessthandot.com/index.php/Union_All
To show you how to handle when you don't have all the columns in each table:
select
1 as seq,col1, col2, col3, cast(null as varchar (40)) as col4
FROM Table1
where ...
UNION ALL
select
2 as seq,'Unknown', col2, null, col4
FROM Table2
where ...
UNION ALL
select
3 as seq ,col1, col2, col3, cast(null as varchar (40)) as col4
FROM Table3
where ...
ORDER BY seq
try:
select
1,col1, col2, col3
FROM Table1
where ...
UNION ALL
select
2,col1, col2, col3
FROM Table2
where ...
UNION ALL
select
3,col1, col2, col3
FROM Table3
where ...
ORDER BY 1
please note that each of the three queries needs to have the same number of columns and that the data types should be consistent also. Also, I used UNION ALL to speed up the query, since there is no use eliminating duplicates between the three queries because the sequence table will guarantee no dups.
to not have the sequence column in the result set try:
SELECT
col1,col2,col3
FROM (select
1 as seq,col1, col2, col3
FROM Table1
where ...
UNION ALL
select
2 as seq,col1, col2, col3
FROM Table2
where ...
UNION ALL
select
3 as seq,col1, col2, col3
FROM Table3
where ...
) dt
ORDER BY seq
you can use a UNION query:
SELECT Field1, Field2, Field3, '1' as Sequence FROM Table1 WHERE SomeCriteria
UNION
SELECT Field7, Field5, Field6, '2' FROM Table2 WHERE SomeCriteria
UNION
SELECT Field4, Field8, Field9, '3' FROM Table3 WHERE SomeCriteria
How about:
create view AZ_VIEW as
select 1 as orderby, tbl1Col1 as col1, tbl1Col2 as col2, tbl1col3 as col3 from Table1 where criteria1='val'
union
select 2, tbl2Col1, tbl2Col2, tbl2col3 from Table2 where criteria2='anotherval'
union
select 3, tbl3Col1, tbl3Col2, tbl3col3 from Table3 where criteria3='athirdval'
;
If your tables share the same columns, you can use Union All:
Select col1, col2, 1 As seq
From table1
Union All
Select col1, col2, 2 As seq
From table1
Union All
Select col1, col2, 3 As seq
From table1
Order By seq
You can UNION the three tables, taking care to ensure that they all return the same number of fields. There is a simple cheat to control the order (seen below):
SELECT * FROM
(
SELECT a, b, c, 1 as ListOrder FROM table1
UNION
SELECT a, b, c, 2 as ListOrder FROM table2
UNION
SELECT a, b, c, 3 as ListOrder FROM table3
)
ORDER BY ListOrder
You can do something like this - WHERE ID = 34 is just a sample filter:
create view vAllRecords as
select 1 as Rank, Field1, Field2 from Table1 where ID = 34
UNION
select 2 as Rank, Field1, Field2 from Table2
UNION
select 3 as Rank, Field1, Field2 from Table3
The use of UNION will remove any duplicates. If you know there will be no duplicates, or you want to see them, the query will run faster with UNION ALL instead.
ORDER BY is not allowed in views, so you'll need to order by Rank when you select from the view:
select *
from vAllRecords
order by Rank