Union two tables having unix_timestamp() function in both - sql

I have two tables A and B. Both has same column names. I want to merge these two table and load it to table C. Table C also have same column names as A and B and one more column in timestamp (this for capturing the merged time). I dont want duplicates in Table C. I tried union but getting duplicate values because one of the column in Table C in Timestamp data type.
For Example, below is my sample query
insert overwrite table TableC
select field1,field2, unix_timestamp() as field3 from table_A
UNION
select field1,field2, unix_timestamp() as field3 from table_B
The two unix_timestamp() function returns different timestamps (just a milli second difference) and I am getting duplicate data because of the timestamp.
Is there anyother way to get the same timestamp for both functions while union ?

unix_timestamp()
Gets current Unix timestamp in seconds.
This function is
non-deterministic and prevents proper optimization of queries -
this has been deprecated since 2.0 in favour of CURRENT_TIMESTAMP
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF
insert overwrite table TableC
select field1,field2, unix_timestamp(current_timestamp) as field3 from table_A
UNION
select field1,field2, unix_timestamp(current_timestamp) as field3 from table_B
Additional work-arounds
insert overwrite table TableC
select field1,field2,unix_timestamp() as field3
from ( select field1,field2 from table_A
union all select field1,field2 from table_B
) t
group by field1,field2
or
insert overwrite table TableC
select field1,field2,unix_timestamp() as field3
from ( select field1,field2 from table_A
union select field1,field2 from table_B
) t

Related

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

oracle - How to insert unique values from a table to another multiple times?

Using Oracle 12c, I have, for example, 5 rows with values 1,2,3,4,5 in a PK column in one table TABLEA. I would like to insert into another table TABLEB the values but 3 times. So TABLE would have 15 rows with values 1,1,1,2,2,2,3,3,3,4,4,4,5,5,5 after the insert. How can I achieve this?
I'm trying to create a script that will insert values from TABLEA to TABLEB if they don't already exist there. Currently I am manually inserting into TABLEB each value from TABLEA 3 times.
You can use cross join. The query would look something like this:
insert into t(pk)
select pk
from table t2 cross join
(select 1 as n from dual union all select 2 from dual union all select 3 from dual
) n;

UNION operation with the same table

I have a scenario where I need to query data in a single row as multiple columns,
Table format is as follows,
SAMPLE_TABLE [ID, REF_TAB_A,REF_TAB_B,REF_TAB_C]
I need REF_TAB_A,REF_TAB_B,REF_TAB_C values in a single column. What I did is use UNION ALL as follows,
SELECT REF_TAB_A FROM SAMPLE_TABLE
UNION ALL
SELECT REF_TAB_B FROM SAMPLE_TABLE
UNION ALL
SELECT REF_TAB_C FROM SAMPLE_TABLE
Is there any other way to do this?? What is the most efficient way to handle such a scenario??
(I'm using oracle 11g)
Thanks in advance.. :D
Using union all generally results in three scans of the table. An alternative approach is a little messier but should have just one scan:
SELECT (case when which = 'A' then REF_TAB_A
when which = 'B' then REF_TAB_B
when which = 'C' then REF_TAB_C
end)
FROM SAMPLE_TABLE cross join
(select 'A' as which from dual union all select 'B' from dual union all select 'C' from dual
) iter
You could alias the columns:
SELECT REF_TAB_A tab FROM SAMPLE_TABLE
UNION ALL
SELECT REF_TAB_B tab FROM SAMPLE_TABLE
UNION ALL
SELECT REF_TAB_C tab FROM SAMPLE_TABLE
What you really need to do, however, is to normalize your database. Whenever you have columns with repeating names like name1, name2, name3, namea, nameb, and namec, it is a sign that you want another table and a 1-many relationship between them.
CREATE TABLE tabs (
tab_id NUMBER PRIMARY KEY,
sample_table_id NUMBER,
tab VARCHAR2(255),
CONSTRAINT FK_sample_table
FOREIGN KEY(sample_table_id)
REFERENCES SAMPLE_TABLE(sample_table_id)
)
Now your query involves a simple JOIN.
SELECT
tab
FROM tabs t
JOIN SAMPLE_TABLE st ON t.sample_table_id = st.sample_table_id
WHERE
...
As an alternative to Gordon's CROSS JOIN trick Oracle has the UNPIVOT clause in the SELECT statement specifically for this situation.
Assuming this table:
create table tmp_test ( a number, b number, c number );
insert all
into tmp_test values (1,2,3)
into tmp_test values (4,5,6)
select * from dual;
The following query would do what you require:
select col
from tmp_test
unpivot ( col for i in (a,b,c) );
COL
----------
1
2
3
4
5
6
6 rows selected.
For this small example an explain plan indicates that using the inbuilt functionality would be more efficient but but test both options and see what's better.

Returning not found values in query

I'm working on a project, and I have a list of several thousand records that I need check. I need to provide the list of the ones NOT found, and provide the query I use to locate them so my superiors can check their work.
I'll admit I'm relatively new to SQL. I don't have access to create temporary tables, which is one way I had thought of to do this.
A basic idea of what I'm doing:
select t.column1, t.column2
from table1 t
where t.column1 in ('value1','value2','value3')
If value1 and value3 are in the database, but value2 is not, I need to display value2 and not the others.
I have tried ISNULL, embedding the query, and trying to select NOT values from the query.
I have searched for returning records not found in a query on Google and on this site, and still found nothing.
I have tried something similar:
First create a table which will contain all such values that you need.
lets say
create table table_values(values varchar2(30));
then try the in clause as below:
select * from table_values tv where tv.value not in (select t.column1
from table1 t);
this will return the values needed.
In SQL Server 2008, you can make derived tables using the syntax VALUES(...)(...)(...), e.g.
select v.value
from (
values ('value1'),('value2'),('value3')
) v(value)
left join table1 t on t.column1 = v.value
where t1.column1 is null
Notes:
Each (...) after VALUES is a single row, and you can have multiple columns.
The v(value) after the derived table is the alias given to the table, and column name(s).
LEFT JOIN keeps the values from the derived table v even when the record doesn't exist in table1
Then, we keep only the records that cannot be matched, i.e. t1.column1 is null
I've switched the first column in your select to the column from v. column2 is removed because it is always null
solution might work in Oracle where dual is single row single column table. You need
one table where you can make virtual select of desired values!
WARNING as I don't have access to db I never tested query below.
SELECT tab_all.col_search, t.column1, t.column2
FROM
(
Select value1 AS col_search from dual
union all
Select value2 from dual
union all
Select value3 from dual
) tab_all left join table1 t
on col_search = t.column1
WHERE t.column1 is null;
I belive sqlserver equivalent of Oracle's
SELECT value1 FROM dual is
SELECT value1 OR SELECT 'value1'.
So try
SELECT tab_all.col_search, t.column1, t.column2
FROM
(
Select value1 AS col_search
union all
Select value2 AS col_search
union all
Select value3 AS col_search
) tab_all left join table1 t
on col_search = t.column1
WHERE t.column1 is null;
As I am not sqlserver person might be that
RichardTheKiwi version of Oracle's select from dual is better.

SQL Append table queries

I have two tables, say table1 with two rows of data say row11 and row12
and table2 with 3 rows of data sat row21, row22, row23
Can anyone provide me with the SQL to create a query that returns
row11
row12
row21
row22
row23
Note: I dont want to create a new table just return the data.
Use UNION ALL, based on the example data:
SELECT * FROM TABLE1
UNION ALL
SELECT * FROM TABLE2
UNION removes duplicates - if both tables each had a row whose values were "rowx, 1", the query will return one row, not two. This also makes UNION slower than UNION ALL, because UNION ALL does not remove duplicates. Know your data, and use appropriately.
select * from table1 union select * from table2
Why not use a UNION?
SELECT
Col1,Col2,Col3
FROM
TABLE1
UNION
SELECT
Col1,Col2,Col3
FROM
TABLE2
Are the columns on the two tables identical?
In MS Access you can achieve the same goal with an INSERT INTO query:
INSERT INTO TABLE1 SELECT * FROM TABLE2;