Oracle Select query with dynamic table name - sql

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.

Related

PostgreSQL query to list all values of a column that are common between tables

I have a column named endate(its values are dates) present in five tables, straddle0, straddle1, straddle2, straddle3 and straddle4. My assumption regarding the data is that, one table's endate values are not present in any of the other mentioned tables(can be repeated in the same table though). But to confirm, I want to list all the endate values that might be present in multiple tables (like 01-01-2017 is present in straddle0 and also in straddle4 or 02-02-2017 is present in straddle1 and also in straddle3 and straddle5).
What is the PostgreSQL query for the same?
I would use UNION ALL and a GROUP BY/HAVING:
Schema (PostgreSQL v13)
CREATE TABLE t1 (
enddate date
);
CREATE TABLE t2 (
enddate date
);
CREATE TABLE t3 (
enddate date
);
INSERT INTO t1
VALUES (CURRENT_DATE), (CURRENT_DATE+1);
INSERT INTO t2
VALUES (CURRENT_DATE), (CURRENT_DATE+2), (CURRENT_DATE+2);
INSERT INTO t3
VALUES (CURRENT_DATE+2), (CURRENT_DATE+3);
Query #1
WITH all_dates AS (
SELECT 't1' AS table_name, enddate
FROM t1
UNION ALL
SELECT 't2' AS table_name, enddate
FROM t2
UNION ALL
SELECT 't3' AS table_name, enddate
FROM t3
)
SELECT enddate, ARRAY_AGG(DISTINCT table_name) AS appears_in
FROM all_dates
GROUP BY 1
HAVING COUNT(DISTINCT table_name) > 1
ORDER BY 1;
enddate
appears_in
2022-05-07T00:00:00.000Z
t1,t2
2022-05-09T00:00:00.000Z
t2,t3
View on DB Fiddle
Not sure what format you want the result in. I made two scripts - a simple one and a more detailed one. Perhaps this is what you need
Here is dbfiddle
with data(dt, t) as (
select distinct endate, 0 from straddle0 union all
select distinct endate, 1 from straddle1 union all
select distinct endate, 2 from straddle2 union all
select distinct endate, 3 from straddle3 union all
select distinct endate, 4 from straddle4
)
select dt, min(t) as t from data group by dt having count(*) = 1;

StartDate invalid identifier

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).

INSERT with UNION ALL returns only the first select result - HIVE Beeline

I want to do a query that inserts the result of table1 with table2 union's result. But when I try on beeline:
insert into table table3
select * from (
select * from table1 t1
where
h_time > '2019-05-01 00:00:00'
and t1.id in (select id from table4)
union all
select * from table2 t2
where
h_time > '2019-05-01 00:00:00'
and t2.id not in (select id from table4)
);
Consider that the both tables 1 and 2 have the same column numbers and datatypes have already fixed previously.
The result in table3 is only the rows of table1. And when I change the position of table 1 and 2, I get only the rows of table2.
Anyone have a guess what's happening?
Tks in advance!
it may be problem with table too, it may not show the actual count sometimes, use select * from tablename. If the count is as expected the run Analyze statement it'll re-compute and repair the statistics

Teradata SQL - Union and Where Clause

have a Teradata SQL UNION query and need to know how I can extract data from 2 tables where date in first part of UNION is before the date in the second part of the UNION query. Example:
Select
name1,date1
from table1
UNION
Select
name2,date2
from table2
where date2 < date1
Would like to see only records where date2 is before date1. This is just an example of what I need to retrieve from my data.
Select
Pat_Name, Provider, Clinic_Encounter_Date
from Clinic table
UNION
Pat_Name, Provider, Hosp_Encounter_Date
from Hospital table
where
Hosp_Encounter_Date < Clinic_Encounter_Date;
My SQL query runs fine, but when I add the WHERE clause I keep getting an error message. Teradata just doesn't like me!!!
Hopefully, this is a bit more helpful. :-)
Thank you in advance for your assistance.
The SQLs in before and after the UNION are independent SQLs, so in the second statement it is not recognizing date1. i.e. the following statement is not valid.
Select name2,date2 from table2 where date2 < date1
You will need to change your statement to
Select
name1,date1
from table1
UNION
Select
name2,date2
from table2
where date2 < (select Min(date1) from table1)

SQL - Getting Most Recent Date From Multiple Columns

Assume a rowset containing the following
EntryID Name DateModified DateDeleted
-----------------------------------------------
1 Name1 1/2/2003 NULL
2 Name1 1/3/2005 1/5/2008
3 Name1 1/3/2006 NULL
4 Name1 NULL NULL
5 Name1 3/5/2008 NULL
Clarification:
I need a single value - the largest non-null date from BOTH columns. So the largest of all ten cells in this case.
SELECT MAX(CASE WHEN (DateDeleted IS NULL OR DateModified > DateDeleted)
THEN DateModified ELSE DateDeleted END) AS MaxDate
FROM Table
For MySQL, Postgres or Oracle, use the GREATEST function:
SELECT GREATEST(ISNULL(t.datemodified, '1900-01-01 00:00:00'),
ISNULL(t.datedeleted, '1900-01-01 00:00:00'))
FROM TABLE t
Both Oracle and MySQL will return NULL if a NULL is provided. The example uses MySQL null handling - update accordingly for the appropriate database.
A database agnostic alternative is:
SELECT z.entryid,
MAX(z.dt)
FROM (SELECT x.entryid,
x.datemodified AS dt
FROM TABLE x
UNION ALL
SELECT y.entryid
y.datedeleted AS dt
FROM TABLE y) z
GROUP BY z.entryid
As a general solution, you could try something like this:
select max(date_col)
from(
select max(date_col1) AS date_col from some_table
union
select max(date_col2) AS date_col from some_table
union
select max(date_col3) AS date_col from some_table
...
)
There might be easier ways, depending on what database you're using.
How about;
SELECT MAX(MX) FROM (
SELECT MAX(DateModified) AS MX FROM Tbl
UNION
SELECT MAX(DateDeleted) FROM Tbl
) T
The answer depends on what you really want. If you simply want the most recent of the two date values then you can do:
Select Max(DateModified), Max(DateDeleted)
From Table
If you are asking for the largest value from either column, then you can simply do:
Select Case
When Max(DateModified) > Max(DateDeleted) Then Max(DateModified)
Else Max(DateDeleted)
End As MaxOfEitherValue
From Table
The above are all valid answers;
But I'm Not sure if this would work?
select IsNull((
select MAX(DateModified)
from table
)
,
(
select MAX(DateDeleted)
from table
)
) as MaxOfEitherValue
from table
Edit 1:
Whilst in the shower this morning, I had another solution:
Solution 2:
select MAX(v) from (
select MAX(DateModified) as v from table
union all
select MAX(DateDeleted) as v from table
) as SubTable
Edit 3:
Damn it, just spotted this is the same solution as Alex k. sigh...
How to find the Latest Date from the columns from Multiple tables
e.g. if the Firstname is in Table1, Address is in Table2, Phone is in Table3:
When you are using with main SELECT statement while selecting other columns it is best written as :
SELECT Firstname
,Lastname
,Address
,PhoneNumber
,
,(SELECT max(T.date_col) from(select max(date_col1) AS date_col from Table1 Where ..
union
select max(date_col2) AS date_col from Table2 Where..
union
select max(date_col3) AS date_col from Table3 Where..
) AS T
) AS Last_Updated_Date
FROM Table T1
LEFT JOIN Table T2 ON T1.Common_Column=T2.Common_Column
LEFTJOIN Table T3 ON T1.Common_Column=T3.Common_Column