hive create view problem: internally casting numbers to something else - hadoop

I'm facing an issue in hive while creating view from a partitioned table. If I use the command below:
create view test_view as select * from table where and year=2000 and month=01 and day=02;
The view gets created but the below selection results in 0 records:
select count(*) from test_view where day='02';
Whereas, the below selection will work just what it's meant to do:
select count(*) from test_view where day='2';
The following command also gives the count(*) result properly:
select count(*) from test_view where day=2;
The important thing here is that day=02 is a physical partition in the actual table, which is fine to the understanding. It's somehow the view creation is interpreting the input integers.
Anyone got any ideas on this?

Related

How to merge two or more unknown tables into one table in Oracle

I'm trying to merge x number of identical tables into one table. The reason we did this is because we want to have, for example 50 columns per table in the database. Tables are created externally via SCADA software called Ignition.
Every time table is created in the database, we want to view the data as one regardless of how many tables the data came from provided that all tables will have the same first three letters for example, Table_1, Table_2, Table_3....so on.
The query/procedure we want to have is like:
step 1: since the tables are unknown we can't do it by simple union, merge insert etc., so we must find all table_name with 'Table' prefix.
SELECT table_name FROM all_tables where table_name like 'Table%'
step 2: this is where the magic begins, it should query one by one each listed table_name in first step, then collect all the data and merge into one table or view.
I tried many ways using PL/SQL but don't know how to proceed with step 2. Is there any way to get what we want to achieve? any possible solutions would be great! :)
Thanks!
Assuming that you are selecting only the common columns from all the tables, you could create a dynamic view, which does a UNION ALL of all the tables starting with "Table" prefix.
DECLARE
v_select CLOB;
BEGIN
SELECT
LISTAGG('SELECT col1,col2,col3 FROM ' || table_name,
' UNION ALL ' || CHR(10) ) WITHIN GROUP
(
ORDER BY table_name
)
INTO v_select
FROM user_tables WHERE table_name LIKE 'TABLE_%';
IF
v_select IS NOT NULL
THEN
EXECUTE IMMEDIATE ' CREATE OR REPLACE VIEW v_all_tabs as ' || v_select;
END IF;
END;
/
Then select from the view by executing the above block(or put it into a procedure ) each time there's a new table added.
select * from v_all_tabs;
If there's a chance of your SQL string exceeding 4000 characters, instead of a single LISTAGG, you could append each select through a simple assignment in PL/SQL in a cursor loop.

how to get select statement query which was used to create table in oracle

I created a table in oracle like
CREATE TABLE suppliers AS (SELECT * FROM companies WHERE id > 1000);
I would like to know the complete select statement which was used to create this table.
I have already tried get_ddl but it is not giving the select statement. Can you please let me know how to get the select statement?
If you're lucky one of these statements will show the DDL used to generate the table:
select *
from gv$sql
where lower(sql_fulltext) like '%create table suppliers%';
select *
from dba_hist_sqltext
where lower(sql_text) like '%create table%';
I used the word lucky because GV$SQL will usually only have results for a few hours or days, until the data is purged from the shared pool. DBA_HIST_SQLTEXT will only help if you have AWR enabled, the statement was run in the last X days that AWR is configured to hold data (the default is 8), the statement was run after the last snapshot collection (by default it happens every hour), and the statement ran long enough for AWR to think it's worth saving.
And for each table Oracle does not always store the full SQL. For security reasons, DDL statements are often truncated in the data dictionary. Don't be surprised if the text suddenly cuts off after the first N characters.
And depending on how the SQL is called the case and space may be different. Use lower and lots of wildcards to increase the chance of finding the statement.
TRY THIS:
select distinct table_name
from
all_tab_columns where column_name in
(
select column_name from
all_tab_columns
where table_name ='SUPPLIERS'
)
you can find table which created from table

Create Materialized View hangs using remote table - even with 0 rows

We're trying to create a simple materialized view based on a remote table, but it just hangs.
The view creation code looks similar to this:
CREATE MATERIALIZED VIEW MV_XYZ
REFRESH FORCE ON DEMAND
AS
SELECT COLUMN1,
COLUMN2,
COLUMN3
FROM TAB1#DBLINK1
WHERE COLUMN4 = 1
Now, if we execute the SELECT statement separately, we get:
#Rows: 237
#Execution Time: 0.8 seconds
That's fairly weird already, but even if we change the SELECT statement to return 0 rows, the view still doesn't get created:
CREATE MATERIALIZED VIEW MV_XYZ
REFRESH FORCE ON DEMAND
AS
SELECT COLUMN1,
COLUMN2,
COLUMN3
FROM TAB1#DBLINK1
WHERE COLUMN4 = 1
AND 1=2 --included this, still hangs;
It appears that the result set is irrelevant to the problem itself.
What could be causing this?
Additional consideration:
We had no issues creating materialized views based on other tables over the same dblink.
query V$session (and v$sqlarea) as these views will provide some clues as to what is going on; you can also check for blocking locks (many scripts available on-line).

How do I get the number of rows in each table I have in my oracle database

Can someone tell me how I can get the number of rows in each table in my oracle database? I have found several queries, but none of them worked because I am using oracle 7 and sqlplus 3.2 and basically all what I found didn't work on it. I just need something that would work on sqlplus 3.2.
Required:
Table Name Rows
Table 1 0
Table 2 5
...
Is it possible to do it with something like a loop? Or what exactly should I do?
if SELECT table_name, num_rows from all_tables doesn't give you what you need.
You could use dynamic SQL and counts as Rahul selected.
Run the below to get results which dynamically build a union on all tables, then run the results as it's own query to get final results.
SELECT 'SELECT ' ||t.name || ' as tName, count(*) as Row_Cnt
FROM ' || t.name || ' UNION ALL '
FROM ALL_TABLES t
Just be sure to remove the last union statement on the last query.
Also note: if you don't have access to see the table, it will not come out in this list!
---Updated ------
So if all_tables doesn't exist none of this will work. Since I don't have a oracle 7 instance handy... could you see if SELECT * FROM dictionary returns anything that might produce a list of all the tables? If you find a view or table object use it in place of all_tables above.
I'm reading the docs for oracle 7 now but finding little easily searchable. thus a guess and check method may go faster.

Does Hive have something equivalent to DUAL?

I'd like to run statements like
SELECT date_add('2008-12-31', 1) FROM DUAL
Does Hive (running on Amazon EMR) have something similar?
Best solution is not to mention table name.
select 1+1;
Gives the result 2. But poor Hive need to spawn map reduce to find this!
Not yet: https://issues.apache.org/jira/browse/HIVE-1558
To create a dual like table in hive where there is one column and one row you can do the following:
create table dual (x int);
insert into table dual select count(*)+1 as x from dual;
Test an expression:
select split('3,2,1','\\,') as my_new_array from dual;
Output:
["3","2","1"]
There is a nice working solution (well, workaround) available in the link, but it is slow as you might imagine.
The idea is that you create a table with a dummy field, create a text file whose content is just 'X', load that text into that table. Viola.
CREATE TABLE dual (dummy STRING);
load data local inpath '/path/to/textfile/dual.txt' overwrite into table dual;
SELECT date_add('2008-12-31', 1) from dual;
Hive does support this function now and also does support many other dates function as well.
You can run query like below in hive, which will add days the provided date in first argument.
SELECT DATE_ADD('2019-03-01', 5);
Hive Date Functions
Quick Solution:
We can use existing table to achieve dual functionality by following query.
SELECT date_add('2008-12-31', 1) FROM <Any Existing Table> LIMIT 1
For example:
SELECT CONCAT('kbdjj','56454') AS a, null AS b FROM tbl_name LIMIT 1
Result
"limit 1" in query is used to avoid multiple occurrences of specified values (kbdjj56454,null).

Resources