StartDate invalid identifier - sql

I have two SELECT statment which I connect using UNION and I get error
ORA-00904: "PUSD2"."STARTDATE": invalid identifier
Since I create first one SELECT statment and run and I get result, and second also, so I run separatly and it works perfect. But when I use UNION I get error pusd2.StartDate invalid identifier.
SELECT * FROM project_users_schedule_dates pusd1
WHERE pusd1.UserID = 196 AND
pusd1.StartDate >= '2020-04-27' AND pusd1.EndDate <= '2020-06-06'
UNION
SELECT * FROM project_users_schedule_dates pusd2
WHERE pusd2.UserID = 196 AND
pusd2.StartDate <= '2020-04-27' AND pusd2. EndDate >= '2020-06-06'
ORDER BY pusd2.StartDate
What is wrong here ? What I made wrong ?
Table structure project_users_schedule_dates

The error likely stems from using an alias in the second union in your ORDER BY clause. However, I might suggest writing your query this way instead:
SELECT DISTINCT *
FROM project_users_schedule_dates
WHERE
UserID = 196 AND
(StartDate >= '2020-04-27' AND EndDate <= '2020-06-06' OR
StartDate <= '2020-04-27' AND EndDate >= '2020-06-06');
This approach brings together the critera from both sides of the union in a single WHERE clause. It then filters duplicates using DISTINCT, instead of the union. Note that in general doing SELECT * in a union query is not desirable, because it makes it impossible to see which columns are being included.

The problem is the ORDER BY clause. If you use UNION, you have to put the order by in an outline query
SQL> create table t ( c1 date ) ;
Table created.
SQL> insert into t values ( sysdate ) ;
1 row created.
SQL> select t.c1 from t union all select x.c1 from t x order by x.c1 ;
select t.c1 from t union all select x.c1 from t x order by x.c1
*
ERROR at line 1:
ORA-00904: "X"."C1": invalid identifier
You have to use an outline query with order by out of the union ( see below ) or use another approximation like the one provided in the other answer.
SQL> select * from ( select t.c1 from t union all select x.c1 from t x ) order by c1 ;
C1
---------
27-AUG-20
27-AUG-20

The way I see it, the last line of your query should be just
ORDER BY StartDate
(of course, if there's such a column in that query).

Related

oracle sql - define date as variable in a with statement

in oracle - i am trying to figure out how to define variables in a with statement.
when i define a variable as a number it works fine:
with a as(
select 100 as query_rows
from dual
)
,b as (
select * from table1 where rownum=query_rows
)
select * from b --working great
however,if i want to define a date as a variable,i keep getting an error:
with a as(
select DATE '2020-10-01' as query_date
from dual
)
,b as (
select * from table1 where table1.date=query_date
)
select * from b -- ORA-00904 : "query_date" is not a valid identifier
from oracle :ORA-00904
You tried to execute a SQL statement that included an invalid column name or the column name is missing. This commonly occurs when you reference an invalid alias in a SELECT statement.
so,why does the first query work and the second one doesn't?
You need to use the CTE table in query as follows:
with a as(
select DATE '2020-10-01' as query_date
from dual
)
,b as (
select * from table1 cross join a where table1.date=a.query_date
)
Select * from b;
It is possible, but you need to refer to cte you are using(here using subquery):
with a as(
select DATE '2020-10-01' as query_date
from dual
) ,b as (
select *
from table1
where table1.date = (SELECT query_date FROM a) -- IN if more than one row is allowed
)
select * from b
Adding to #Tejash, you don't need to use b:
with a as(
select DATE '2020-10-01' as query_date
from dual
)
select * from table1 cross join a where table1.date=a.query_date

Join other table in SQL with dual table

SQL Console
select trunc((:FromDate)+1)-rn as date_Val
from ( select rownum rn
from dual
connect by level <= ((:FromDate)-(:todate))+1)
order by trunc(:FromDate)-rn
I want to join this column with other tables. When I write in Sub Query return more than one row error show
Turn it into a cte and write the rest of your query under it:
with dateseq as
(
select trunc((:FromDate)+1)-rownum as date_val
from dual
connect by level <= ((:FromDate)-(:todate))+1)
)
select * from dateseq inner join ...
ps: simplified your query a bit- you don't need the subquery

Accesing parent identifier in an ordered nested subquery

I need a query to get the value of an item together with the value of the previous item if exists.
I am using the following query (a simplification of the actual):
select v1.value item_value,
nvl(
(
select * from (
select v2.value
from ITEMS v2
where v2.insert_date<v1.insert_date
order by v2.insert_date desc
) where rownum=1
), 0
) as previous_value
from ITEMS v1
where v1.item_id=1234
This query won't work (ORA-00904) because I am using v1.insert_date in an inner select with two levels of nesting.
How can I achieve this with Oracle 11?
I think you can achieve this with analytic function LAG. More info about analytic functions LAG LEAD
I created a sample query:
with items as (
select 1 as value, sysdate as insert_date from dual
union all
select 2 as value, sysdate-1 as insert_date from dual
union all
select 3 as value, sysdate+1 as insert_date from dual
)
select v1.value item_value,
lag(v1.value,1,0) over (order by v1.insert_date desc) as previous_value,insert_date
from ITEMS v1
order by insert_date desc

Oracle Select query with dynamic table name

I m trying to create a complicated select query which uses temp tables and syntax as below
with as
table1
( select start_date, end_date ....somequery - returns only 1 row ),
table2
( select ... somequery use table1 columns in where clause.. ),
table3
( select ... use table1 columns in where clause .. )
select * from
select case when ( start_date < sysdate -1000 and end_date > sysdate ) then 'table2' else 'table3' end from table1
where rownum < 10
So logic is simple based on return value from table1 i may want to query table 2 or may want to query table3
Problem: Oracle doesnt allow table name to be dynamically generated in a sql query
I know i can write a procedure and use EXECUTE IMMEDIATE but for some reason i have to do everything via a single query. Any help will be greatly appreciated.
You can do something like this for your main select:
select *
from table1 cross join
table2
where start_date < sysdate - 1000 and end_date > sysdate and rownum < 10
union all
select *
from table1 cross join
table3
where not (start_date < sysdate - 1000 and end_date > sysdate) and rownum < 10
The idea is to use union all for the two conditions and where to guarantee that no rows are returned subject to your conditions. Note that this form of the where statement do not take into account NULL values for start_date or end_date.
I suspect that there might be another way to write this query, if more details about table2 and table3` were available.

Oracle Query fetching table name alongwith column name

select trx_id,refernce number from
(select * from abcd_1_txt union
select * from abcd_2_txt union
select * from abcd_3_txt union
select * from abcd_4_txt)
where trx_id in (123,321,1234)
In the query all the tables are of same format, same column names and same number of columns.
After running this query, surely i will get some data.
My question --- is there any way to know from which of these tables, i am getting the output.
Try to add a column with number of query as below
select qrynum, trx_id,refernce number from
(select 1 as qrynum,* from abcd_1_txt union
select 2,* from abcd_2_txt union
select 3,* from abcd_3_txt union
select 4,* from abcd_4_txt)
where trx_id in (123,321,1234)
as Joe W said in the comment below you can also use name of the table instead of query number, short example:
select tabname, trx_id,refernce number from
(select 'abcd_1_txt' as tabname,* from abcd_1_txt union
...
where trx_id in (123,321,1234)
but both ways don't eliminate duplicates, so you can use union all instead of union. Other way to do that is to run quires separately with the condition
select * from abcd_1_txt where trx_id in (123,321,1234)
select * from abcd_2_txt where trx_id in (123,321,1234)
.
.
.