Can I nest "WITH" clause in Oracle SQL? - sql

Following query gives me an error:
"ORA-32034: Unsupported use of WITH clause"
WITH table_B as
(
SELECT * FROM (
WITH table_A AS
(SELECT 'Akshay' as NAME FROM DUAL)
SELECT NAME FROM table_A
) WHERE NAME LIKE '%Aks%' ---<<< Note a filter here
)
SELECT * from table_B;
Is there a way out? Thanks

You should change your query to:
WITH table_a AS
(
SELECT 'Akshay' as name
FROM dual
)
,table_b AS
(
SELECT name
FROM table_a
WHERE name LIKE '%Aks%'
)
SELECT *
FROM table_b;

We can use like following:-
WITH
table_A AS
(SELECT 'Akshay' as NAME FROM DUAL),
table_B AS
(SELECT * FROM table_A where NAME like 'Aks%') --<< Adding filter here now
SELECT * FROM table_B;
Cheers!

Related

Can we select count(query) from table

SELECT COUNT(ANOTHER SELECT QUERY) FROM DUAL.
Can we get the results this way or is there any other way?
An example could help:
SQL> create table tabTest as (select 1 x from dual);
Table created.
SQL> select count( select * from tabTest ) from dual;
select count( select * from tabTest ) from dual
*
ERROR at line 1:
ORA-00936: missing expression
SQL> select count(*) from (select * from tabTest);
COUNT(*)
----------
1
You can use a derived table (aka "sub-query")
select count(*)
from (
.... your query here ...
);

Oracle SQL Query IN

I have following query, that's not working.
select * from table where id in (
1,2, (select id from another_table)
)
How i can rewrite it?
How about
select * from table
where id in (1,2)
or id in (select id from another_table)
Take care and use parentheses when adding additional WHERE-conditions using and!!!
select *
from table
where id in (1,2) OR id in(
select id from another_table
)
select * from table where id in (
select 1 as id from dual
union all
select 2 as id from dual
union all
select id from another_table
)
select * from table where id in (
select 1 from dual
union all
select 2 from dual
union all
select id from another_table);
I'm using union because this is faster than using an OR clause which also can be used.

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

Count rows in more than one table with tSQL

I need to count rows in more than one table in SQL Server 2008. I do this:
select count(*) from (select * from tbl1 union all select * from tbl2)
But it gives me an error of incorrect syntax near ). Why?
PS. The actual number of tables can be more than 2.
In case you have different number of columns in your tables try this way
SELECT count(*)
FROM (
SELECT NULL as columnName
FROM tbl1
UNION ALL
SELECT NULL
FROM tbl2
) T
try this:
You have to give a name to your derived table
select count(*) from
(select * from tbl1 union all select * from tbl2)a
I think you have to alias the SELECT in the FROM clause:
select count(*)
from
(
select * from tbl1
union all
select * from tbl2
) AS SUB
You also need to ensure that the * in both tables tbl1 and tbl2 return exactly the same number of columns and they have to be matched in their type.
I don't like doing the union before doing the count. It gives the SQL optimizer an opportunithy to choose to do more work.
AlexK's (deleted) solution is fine. You could also do:
select (select count(*) from tbl1) + (select count(*) from tbl2) as cnt

Oracle create table using with clause

Can I create a table from a query formed using with clause?
Sure:
CREATE TABLE t
AS
WITH some_data AS (
SELECT 1 as some_value
FROM dual
UNION ALL
SELECT 2
FROM dual
)
SELECT *
FROM some_data
The CREATE TABLE table_name AS statement creates a table based on a select statement. The solution for a with clause will be :
CREATE TABLE t
AS
SELECT * FROM (
WITH some_data AS (
SELECT 1 as some_value
FROM dual
UNION ALL
SELECT 2
FROM dual
)
);
For multiple CTE (common table expressions; i.e. multiple WITH clause), I found the same syntax worked. i.e.
CREATE TABLE schema.table_name as
WITH table1 as (SELECT 1),
table2 as (SELECT 2)
select * from table2
will create the table_name in the schema from the select statement