Need to add a constant value in a column while loading a hive table - hive

I created a table named table1 in hive and i need to insert data from table2 into table1. I used the below statemnt to get the output.
Also i need to add a new column with some constant value -- colx = 'colval' along with the columns in table2 but am not sure how to add it.. Thanks!
INSERT INTO TABLE table1 select * FROM table2;

If you are willing to drop table1 and recreate it from scratch, you could do this:
-- I'm using Hive 0.13.0
DROP TABLE IF EXISTS table1;
CREATE TABLE table1 AS SELECT *, 'colval' AS colx FROM TABLE2;
If that is not an option for some reason, you can use INSERT OVERWRITE:
ALTER TABLE table1 ADD COLUMNS (colx STRING); -- Assuming you haven't created the column already
INSERT OVERWRITE TABLE table1 SELECT *, 'colval' FROM table2;

Related

SQL Server Insert Into Table containing a column "Timestamp (Rowversion)"

I'm creating a C# Winforms application for recipe management in an industrial environment.
I created a SQL Server table with 130 columns. The table contains a column called CheckData (of datatype Timestamp), which I use to detect changes made to a row.
If I insert a new row to that table all works fine. The code I use is:
INSERT INTO tablename (Column1, column2, column3, column4)
VALUES (value1, value2, value3, value4)
I just assign values to major columns, the others get their default value. I do not assign a value to the timestamp field since it's written by the system.
Additionally, I want to copy a row from this table to the same table (duplicate a data record).
I copy the source row to a temporary table, drop the ID (primary key) and the timestamp fields in that temporary table and try to insert that only row in the temporary table into the table. This fails.
Here's the code:
SELECT *
INTO #temptable
FROM tablename
WHERE Recipe_No = 8;
ALTER TABLE #temptable DROP COLUMN ID, CHECKDATA;
ALTER TABLE #temptable REBUILD;
UPDATE #temptable
SET Recipe_No = 9, Recipe_Name = 'Test'
WHERE Recipe_No = 8;
INSERT INTO tablename
SELECT * FROM #temptable;
I don't understand where the difference is between inserting a new row thru INSERT INTO xxx (yyy) VALUES (zzz) and INSERT INTO xxx SELECT * FROM yyy. In both cases I don't try to write the timestamp value in the new row.
Does anybody have an idea what I'm missing here?
I don't understand where the difference is between inserting a new row thru INSERT INTO xxx (yyy) VALUES (zzz) and INSERT INTO xxx SELECT * FROM yyy.
With this,
INSERT INTO xxx SELECT * FROM yyy.
you are failing to specify the column mappings from the SELECT to the target table. You should always use
INSERT INTO xxx (Column1, Column2, . . .)
SELECT (Column1, Column2, . . .)
FROM yyy
Here's a simplified example of what you're attempting:
drop table if exists t
create table t(id int, a int)
insert into t(id,a) values (1,1)
select * into #t from t where id = 1
alter table #t drop column id
insert into t select * from #t
and it will fail with
Msg 213, Level 16, State 1, Line 12
Column name or number of supplied values does not match table definition.
because the temp table doesn't even have the same number of columns. And even if it did, you wouldn't know for sure that the column mappings were correct.
It is failing because essentially your command
INSERT INTO tablename SELECT * FROM #temptable;";
Is telling SQL - "Insert everything into this table from this temp table."
While you can work around this, I would say why don't you just try inserting into only the columns made available in your current table with only the values you would like to include. Instead of needing to drop the columns/values, you just don't import it to begin with.
An alternative - if you can write to a helper table, it may be beneficial to INSERT INTO that helper table, as opposed to a temp table, the values you have. Then transform that helper table, and THEN you can do INSERT INTO final_table SELECT * FROM helper. This should give you the results you're looking for.
I hope this is helpful, and I hope it explains why your current command is failing.

Save return values from INSERT...RETURNING into temp table (PostgreSQL)

I have a table table1 with columns id,value1 and value2.
Also I have a query
INSERT INTO table1(value1,value2) SELECT value3,value4 FROM table2 RETURNING id
that returns set of ids.
I want to store return values (these ids) in some temp table. Something like that:
INSERT INTO TEMP temp1 INSERT INTO table1(value1,value2) SELECT value3,value4 FROM table2 RETURNING id
How can I do it?
DBMS is PostgreSQL
with inserted as (
INSERT INTO table1 (value1,value2)
SELECT value3,value4
FROM table2
RETURNING id
)
insert into temp
select id
from inserted;
This requires Postgres 9.2 or later.
Two options.
If you need it just for one follow-up query, a with statement (see the horse's answer) is the easiest.
If you need it for more than one follow-up query, the other option is to not use insert ... returning, but rather create table as:
CREATE TEMPORARY TABLE foo AS
SELECT value3,value4 FROM table2
Caveats: if necessary, create the indexes you need on the table -- and analyze it if you do.

Hive insert query like SQL

I am new to hive, and want to know if there is anyway to insert data into Hive table like we do in SQL. I want to insert my data into hive like
INSERT INTO tablename VALUES (value1,value2..)
I have read that you can load the data from a file to hive table or you can import data from one table to hive table but is there any way to append the data as in SQL?
Some of the answers here are out of date as of Hive 0.14
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML#LanguageManualDML-InsertingvaluesintotablesfromSQL
It is now possible to insert using syntax such as:
CREATE TABLE students (name VARCHAR(64), age INT, gpa DECIMAL(3, 2));
INSERT INTO TABLE students
VALUES ('fred flintstone', 35, 1.28), ('barney rubble', 32, 2.32);
You can use the table generating function stack to insert literal values into a table.
First you need a dummy table which contains only one line. You can generate it with the help of limit.
CREATE TABLE one AS
SELECT 1 AS one
FROM any_table_in_your_database
LIMIT 1;
Now you can create a new table with literal values like this:
CREATE TABLE my_table AS
SELECT stack(3
, "row1", 1
, "row2", 2
, "row3", 3
) AS (column1, column2)
FROM one
;
The first argument of stack is the number of rows you are generating.
You can also add values to an existing table:
INSERT INTO TABLE my_table
SELECT stack(2
, "row4", 1
, "row5", 2
) AS (column1, column2)
FROM one
;
Slightly better version of the unique2 suggestion is below:
insert overwrite table target_table
select * from
(
select stack(
3, # generating new table with 3 records
'John', 80, # record_1
'Bill', 61 # record_2
'Martha', 101 # record_3
)
) s;
Which does not require the hack with using an already exiting table.
You can use below approach. With this, You don't need to create temp table OR txt/csv file for further select and load respectively.
INSERT INTO TABLE tablename SELECT value1,value2 FROM tempTable_with_atleast_one_records LIMIT 1.
Where tempTable_with_atleast_one_records is any table with atleast one record.
But problem with this approach is that If you have INSERT statement which inserts multiple rows like below one.
INSERT INTO yourTable values (1 , 'value1') , (2 , 'value2') , (3 , 'value3') ;
Then, You need to have separate INSERT hive statement for each rows. See below.
INSERT INTO TABLE yourTable SELECT 1 , 'value1' FROM tempTable_with_atleast_one_records LIMIT 1;
INSERT INTO TABLE yourTable SELECT 2 , 'value2' FROM tempTable_with_atleast_one_records LIMIT 1;
INSERT INTO TABLE yourTable SELECT 3 , 'value3' FROM tempTable_with_atleast_one_records LIMIT 1;
No. This INSERT INTO tablename VALUES (x,y,z) syntax is currently not supported in Hive.
You could definitely append data into an existing table. (But it is actually not an append at the HDFS level). It's just that whenever you do a LOAD or INSERT operation on an existing Hive table without OVERWRITE clause the new data will be put without replacing the old data. A new file will be created for this newly inserted data inside the directory corresponding to that table. For example :
I have a file named demo.txt which has 2 lines :
ABC
XYZ
Create a table and load this file into it
hive> create table demo(foo string);
hive> load data inpath '/demo.txt' into table demo;
Now,if I do a SELECT on this table it'll give me :
hive> select * from demo;
OK
ABC
XYZ
Suppose, I have one more file named demo2.txt which has :
PQR
And I do a LOAD again on this table without using overwrite,
hive> load data inpath '/demo2.txt' into table demo;
Now, if I do a SELECT now, it'll give me,
hive> select * from demo;
OK
ABC
XYZ
PQR
HTH
Ways to insert data into Hive table:
for demonstration, I am using table name as table1 and table2
create table table2 as select * from table1 where 1=1;
or
create table table2 as select * from table1;
insert overwrite table table2 select * from table1;
--it will insert data from one to another. Note: It will refresh the target.
insert into table table2 select * from table1;
--it will insert data from one to another. Note: It will append into the target.
load data local inpath 'local_path' overwrite into table table1;
--it will load data from local into the target table and also refresh the target table.
load data inpath 'hdfs_path' overwrite into table table1;
--it will load data from hdfs location iand also refresh the target table.
or
create table table2(
col1 string,
col2 string,
col3 string)
row format delimited fields terminated by ','
location 'hdfs_location';
load data local inpath 'local_path' into table table1;
--it will load data from local and also append into the target table.
load data inpath 'hdfs_path' into table table1;
--it will load data from hdfs location and also append into the target table.
insert into table2 values('aa','bb','cc');
--Lets say table2 have 3 columns only.
Multiple insertion into hive table
Yes you can insert but not as similar to SQL.
In SQL we can insert the row level data, but here you can insert by fields (columns).
During this you have to make sure target table and the query should have same datatype and same number of columns.
eg:
CREATE TABLE test(stu_name STRING,stu_id INT,stu_marks INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
INSERT OVERWRITE TABLE test SELECT lang_name, lang_id, lang_legacy_id FROM export_table;
To insert entire data of table2 in table1. Below is a query:
INSERT INTO TABLE table1 SELECT * FROM table2;
You can't do insert into to insert single record. It's not supported by Hive. You may place all new records that you want to insert in a file and load that file into a temp table in Hive. Then using insert overwrite..select command insert those rows into a new partition of your main Hive table. The constraint here is your main table will have to be pre partitioned. If you don't use partition then your whole table will be replaced with these new records.
Enter the following command to insert data into the testlog table with some condition:
INSERT INTO TABLE testlog SELECT * FROM table1 WHERE some condition;
I think in such scenarios you should be using HBASE which facilitates such kind of insertion but it does not provide any SQL kind of query language. You need you use Java API of HBASE like the put method to do such kind of insertion. Moreover HBASE is column oriented no-sql database.
You still can insert into complex type in Hive - it works
(id is int, colleagues array)
insert into emp (id,colleagues) select 11, array('Alex','Jian') from (select '1')
you can add values to specific columns as well, just specify the column names in which you like to add corresponding values:
Insert into Table (Col1, Col2, Col4,col5,Col7) Values ('Va11','Va2','Val4','Val5','Val7');
Make sure the columns you skip dont have not null value type.
There are few properties to set to make a Hive table support ACID properties and to insert the values into tables as like in SQL .
Conditions to create a ACID table in Hive.
The table should be stored as ORC file. Only ORC format can support ACID prpoperties for now.
The table must be bucketed
Properties to set to create ACID table:
set hive.support.concurrency =true;
set hive.enforce.bucketing =true;
set hive.exec.dynamic.partition.mode =nonstrict
set hive.compactor.initiator.on = true;
set hive.compactor.worker.threads= 1;
set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set the property hive.in.test to true in hive.site.xml
After setting all these properties , the table should be created with tblproperty 'transactional' ='true'. The table should be bucketed and saved as orc
CREATE TABLE table_name (col1 int,col2 string, col3 int) CLUSTERED BY col1 INTO 4
BUCKETS STORED AS orc tblproperties('transactional' ='true');
Now its possible to inserte values into the table like SQL query.
INSERT INTO TABLE table_name VALUES (1,'a',100),(2,'b',200),(3,'c',300);
Yes we can use Insert query in Hive.
hive> create table test (id int, name string);
INSERT: INSERT...VALUES is available starting in version 0.14.
hive> insert into table test values (1,'mytest');
This is going to work for insert. We have to use values keyword.
Note: User cannot insert data into a complex datatype column (array, map, struct, union) using the INSERT INTO...VALUES clause.

SQL: use SELECT to INSERT data into table with extra column

I have a table Table1 with 59 columns. Table2 is a copy of Table1 with one extra column, COLUMN 60 at the end. Hence table2 has 60 columns.
I am trying to copy the values from table1 to table2 and set value of the extra column in table2 to "value"
Something like this
INSERT INTO Table2
SELECT * FROM Table1, 'value' AS 'COLUMN 60'
How can I do this? Using the code above give me an error:
An explicit value for the identity column in table 'TableLocation' can only be specified when a column list is used and IDENTITY_INSERT
is ON.
I do not want to specify column names because there are too many of those.
Try this:
SET IDENTITY_INSERT dbo.Table2 ON
INSERT INTO Table2
SELECT *, 'value' AS 'COLUMN 60' FROM Table1
SET IDENTITY_INSERT dbo.Table2 OFF
You know that you can just drag the column names from SSMS right? Navigate to the table and then drag the columns folder into the query window, it will list all the columns for you
Now if you want to preserve the identity values then use
SET IDENTITY_INSERT dbo.Table2 ON
--INSERT HERE
-- make sure to list all the columns, it is required
SET IDENTITY_INSERT dbo.Table2 OFF
Does it really need to be done in one statement?
INSERT INTO Table2
SELECT * FROM Table1
ALTER TABLE Table2
ADD Column60 varchar

In MySQL, how to copy the content of one table to another table within the same database?

I am new to MySQL. I would like to copy the content of one table to another table within the same database. Basically, I would like to insert to a table from another table. Is there easy way of doing this?
If the tables have the same structure:
INSERT INTO TARGET_TABLE SELECT * FROM SOURCE_TABLE;
If the tables have different structures:
INSERT INTO TARGET_TABLE (`col1`,`col2`) SELECT `col1`,`col2` FROM SOURCE_TABLE;
You can also add conditions:
INSERT INTO TARGET_TABLE (`col1_`,`col2_`) SELECT `col1`,`col2` FROM SOURCE_TABLE WHERE `foo`=1
If the table doesn't exist, you can create one with the same schema like so:
CREATE TABLE table2 LIKE table1;
Then, to copy the data over:
INSERT INTO table2 SELECT * FROM table1
If table1 is large and you don't want to lock it for the duration of the copy process, you can do a dump-and-load instead:
CREATE TABLE table2 LIKE table1;
SELECT * INTO OUTFILE '/tmp/table1.txt' FROM table1;
LOAD DATA INFILE '/tmp/table1.txt' INTO TABLE table2;
This worked for me,
CREATE TABLE newtable LIKE oldtable;
Replicates newtable with old table
INSERT newtable SELECT * FROM oldtable;
Copies all the row data to new table.
If you want to create and copy the content in a single shot, just use the SELECT:
CREATE TABLE new_tbl SELECT * FROM orig_tbl;
This worked for me. You can make the SELECT statement more complex, with WHERE and LIMIT clauses.
First duplicate your large table (without the data), run the following query, and then truncate the larger table.
INSERT INTO table_small (SELECT * FROM table_large WHERE column = 'value' LIMIT 100)
Super simple. :-)
CREATE TABLE target_table SELECT * FROM source_table;
It just create a new table with same structure as of source table and also copy all rows from source_table into target_table.
CREATE TABLE target_table SELECT * FROM source_table WHERE condition;
If you need some rows to be copied into target_table, then apply a condition inside where clause
Try this. Works well in my Oracle 10g,
CREATE TABLE new_table
AS (SELECT * FROM old_table);