How to update table without using update keyword - sql

I have table a ,table b with same columns .I want to replace the value in table b with table a value without using update keyword.

The question could use a bit more detail on the table structure, what exactly you're trying to accomplish, and what precludes you from using UPDATE, but here goes:
CREATE TABLE #tempTable (col1, col2, col3, ...)
INSERT INTO #tempTable
SELECT
b.col1
, b.col2
, a.col3
, ...
FROM a
INNER JOIN b
ON a.col1 = b.col1
DELETE FROM b
WHERE col1 IN (SELECT col1 FROM a)
INSERT INTO b
SELECT
col1
, col2
, col3
, ...
FROM #TempTable
Which of course makes the bold assumption that Table a and b share a primary key, and that Table b doesn't have any constraint that would prevent deletion of matched rows. Please, provide some more detail and I'll update my answer accordingly.

Related

Why can't we use/refer to derived table in subquery

I wonder why can't a subquery use a derived table as its derived table (Query2), even though it can access the attribute of the derived table (Query1)?
Query1
select B.col1, col2 from dummy B
where B.col1 = (select col1 from dummy A where B.col1 = 'aa' and A.col1 = B.col1 limit 1);
Here we can use B.col1.
Query2
select B.col1, col2 from dummy B
where B.col1 = (select col1 from B where B.col1 = 'aa' limit 1);
Here we can't use B. The error says B doesn't exist.
You can find the sqlfiddle here.
Because the first reference is a correlated reference. A table alias is a reference to a particular "instance" of a table in the query, not another "table" itself.
If you want that ability, use a CTE:
with b as (
select d.*
from dummy d
)
Then you can use b multiple times in the ensuing query.
The problem is that in your second query you are trying to select from the table that does not exist and in your first query you are referring to the column that does.
In both query's the B and the A letters are only aliases not tables.
Having that in mind, lets remove the aliases in the second query:
select col1, col2 from dummy
where col1 = (select col1 from where col1 = 'aa' limit 1);
Do you see something missing now in the query structure ?
To conclude, from your question it seems you do not understand which B is the problem. This one: FROM B and not this one where B.col1.
Hope this helps...

append column from one table to another table in Oracle

Suppose i have one table named A with 3 columns(1 id column),and a table named B with two columns(1 id column).Table A and table B can join using column id.
Now I want to append one column from table B to table A by sql statements。so after executing,table A will have 4 columns.Both table A and table B have million rows,how can I do it efficiently?
Assuming this is a one-off consolidation of tables and you have a reason to do this rather than using a join (with or without a view):
alter table a add (col4 varchar2(10)); -- or whatever data type you actually need
merge into a
using b
on (b.id = a.id)
when matched then update set a.col4 = b.col4;
You could do a correlated updated:
update a set col4 = (
select col4 from b where b.id = a.id
);
but a merge is probably going to be quicker.
There are 2 steps to perform:
Changing the data model (ie. specifying the additional column for A)
Fill the column with suitable values.
These operations can be folded together if you can afford the resources to temporarily hold the data contained in A and B twice:
CREATE TABLE C AS (
SELECT a.id
, a.col2
, a.col3
, b.col2 AS col4
FROM A a
INNER JOIN B b ON ( b.id = a.id )
);
DROP TABLE A;
RENAME C TO A;
While the Alex Poole's answer is more efficient, the above solution works on oracle versions before 9i (esoteric) and on other rdbms ( syntax to rename the table might differ a bit, eg. alter table C rename to A in postgresql 9.x+)

Creation of pipe-delimited hive table - duplicate ids

I'm trying to create a pipe-delimited hive table using these commands:
CREATE TABLE IF NOT EXISTS tableA (
id string,
col1 double,
col2 double,
col3 double,
col4 double,
col5 double,
col6 double,
col7 double
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'
tblproperties ("skip.header.line.count"="1");
INSERT INTO TABLE TABLEA
select a.id
b.col1,
b.col2,
b.col3,
b.col4,
b.col5,
b.col6,
b.col7
FROM customerTable as a left join factTable as b on a.id = b.id;
I get duplicate records in the new table, tableA. I checked using
select count(distinct id) as cnt from tableA ;
Whereas if I create a normal hive table like this, I don't get any duplicate ids:
Create table if not exists tableA as
select a.id
b.col1,
b.col2,
b.col3,
b.col4,
b.col5,
b.col6,
b.col7
FROM customerTable as a left join factTable as b on a.id = b.id;
The table created is in order of 80 Million rows but the difference in the number of records ( duplicate records) is only 58 records.
Not sure whats going on. I guess the problem is with how I'm creating the pipe-delimited hive table. Any help would be appreciated.
Remove tblproperties ("skip.header.line.count"="1"); property in your create table statement and run the insert statement again.

Retrieving Common rows from two tables having Duplicate records

Its my first question, so don't know where I might go wrong.
Here is my scenario :
I have two tables : tblA and tblB. A procedure that first fills some data in tblA and then the same data in tblB. Now due to certain glitch in procedure query, some values of certain columns were not inserted in tblB but in tblA. I now want to update tblB with the records in tblA. I can't find the corresponding records for update.
For easing the task I have given the sample ready to use query
--DROP TABLE #tblA
--DROP TABLE #tblB
--TRUNCATE TABLE #tblA
--TRUNCATE TABLE #tblB
CREATE TABLE #tblA (col1 char(2), col2 char(2), col3 int, col4 char)
CREATE TABLE #tblB (ID char(2),col1 char(2), col2 char(2), col3 int, col4 char)
INSERT INTO #tblA VALUES ('A','B',1,'C')
INSERT INTO #tblA VALUES ('A1','B',2,'C')
INSERT INTO #tblA VALUES ('A1','B',3,'C')
INSERT INTO #tblB VALUES ('I1','A','B',NULL,'C') -- Here we can see that values could not be inserted in col3
INSERT INTO #tblB VALUES ('I2','A1','B',NULL,'C')
INSERT INTO #tblB VALUES ('I3','A1','B',3,'C')
What I have tried so far (excluding other queries that I tried, this gives me the closest result)
(i've even tried the commented section)
--UPDATE B
--SET B.col3=A.col3
SELECT DISTINCT A.*, B.*
FROM #tblA A
INNER JOIN #tblB B
ON 1=1
AND A.col1=B.col1
AND A.col2 = B.col2
AND A.col4 = B.col4
--AND (A.col3<>B.col3)
AND (B.col3 IS NULL OR (B.col3 IS NOT NULL AND A.col3=B.col3))
--AND B.col3 IS NULL
The result I get is as followed:
col1 col2 col3 col4 ID col1 col2 col3 col4
A B 1 C I1 A B NULL C
A1 B 2 C I2 A1 B NULL C
A1 B 3 C I2 A1 B NULL C
A1 B 3 C I3 A1 B 3 C
What modification should I do in my select query (which is going to be my update query) so that I get result as followed : (result that removes third row)
col1 col2 col3 col4 ID col1 col2 col3 col4
A B 1 C I1 A B NULL C
A1 B 2 C I2 A1 B NULL C
A1 B 3 C I3 A1 B 3 C
Unfortunately, based on the information you have given, I don't think there is a good generalized solution. I'd need more information about the possible patterns. As asked, the obvious answer is:
SELECT *
FROM #tblA a
inner join #tblb b
on a.col1=b.col1
and a.col2 = b.col2
and a.col4 = b.col4
and a.col3 = right(b.ID,1)
alternatively, the last line could be and a.col3 = coalesce(b.col3,right(b.ID,1))
Which depends on the ID in #tblb being reflected in Col3. I don't think that's what you want. From an algorithmic point of view, if you can't depend on a meaningful ID, I'm not sure there is a good way to do this. If you can describe the general angorithm you want to apply, then we can write the code to match it.
For example, something that might be meaningful is:
Tbla joins to tblb on all columns
When the join fails, I want to pick the first record from tblb that:
matches columns 1, 2, and 4 in table a
has not already been joined to tbla when sorted by ID
In certain situations I could see that algorithm being useful. But in essence, your are joining tables with duplicate keys, which gets you a cross join on the records where the key is duplicated.
Hope this helps. If you clarify a bit more what you are trying to do, I might be able to help a bit more.
UPDATE:
If, as you say in your comment, you simply want to make sure the two tables match exactly, then you can use the following code:
CREATE TABLE #tblA (col1 char(2), col2 char(2), col3 int, col4 char)
CREATE TABLE #tblB (col1 char(2), col2 char(2), col3 int, col4 char)
INSERT INTO #tblA VALUES ('A','B',1,'C')
INSERT INTO #tblA VALUES ('A1','B',2,'C')
INSERT INTO #tblA VALUES ('A1','B',3,'C')
INSERT INTO #tblB VALUES ('A','B',NULL,'C')
INSERT INTO #tblB VALUES ('A1','B',NULL,'C')
INSERT INTO #tblB VALUES ('A1','B',3,'C')
delete from #tblb
where NOT Exists (Select * from #tbla a
where a.col1 = #tblb.col1
and a.col2 = #tblb.col2
and a.col3 = #tblb.col3
and a.col4 = #tblb.col4)
INSERT #tblb
SELECT * from #tbla
where not exists (select * from #tblb b
where b.col1 = #tbla.col1
and b.col2 = #tbla.col2
and b.col3 = #tbla.col3
and b.col4 = #tbla.col4)
select * from #tbla a
inner join #tblb b
on b.col1 = a.col1
and b.col2 = a.col2
and b.col3 = a.col3
and b.col4 = a.col4
Of course, depending on the size of the table, the size of the row, the indexing of both tables, and how often you run it, it might make more sense to simply drop and reinsert.
It is possible to only update the columns that are incorrect, but I think the coding and maintenance overhead would no be worth it, not to mention that performance would probably be pretty bad.
Does this help?
you don't want to use inner join as there are multiple values comes, you want TOP 1 or Top First record's Col3 value.
So I update the update query as below and this update the result as you want.
update #tblB
SET col3=
( select top 1 a.col3 from #tblA a where A.col1=#tblB.col1
AND A.col2 = #tblB.col2
AND A.col4 = #tblB.col4)
select * from #tblB

using sql create a new table with 2 fields, field1 from tableA and field1 from table B

Am new to SQL and am stuck here with a very simple-looking query request.
I have 2 tables, both having exactly the same structure (IE same no. of columns, same no. Of rows) except for the actual contents. so for example,tableA has 2 columns called col1&col2; tableB has 2 columns too called col1&col2. Now I want to create a 3rd new tale, where 1st column is tableA's col1, and 2nd column is tableB's col1. preferably the name of the 1st column is fromTableA, and name of 2nd column is fromTableC. How do I achieve this please? I tried all the following ways but I always get the same error: "number of query values and destination fields are not the same."
variation 1:
insert into newTable(fromTable1,fromTable2)
select col1 from table1
select col1 from table2
variation 2:
insert into newTable(fromTable1,fromTable2)
select col1 from table1,col1 from table2
variation 3:
insert into newTable(fromTable1,fromTable2)
select col1 from table1, table2
Presumably you have fields in the two tables that can be joined, so this:
insert into newtable (romTable1,fromTable2)
select a.col1, b.col1
from table1 a, table2 b
where a.col1 = b.col1;
The a/b are aliases that differentiate between the two columns in each table. If you don't have fields to join then whatever you're trying to do probably needs a rethink.
You may try following sql query to achieve your purpose:
with OrderedTableA as (
select row_number() over (order by Col1) RowNum, *
from TableA (nolock)
),
OrderedTableB as (
select row_number() over (order by Col1) RowNum, *
from TableB (nolock)
)
select T1.Col1, T2.Col2 into TableC
from OrderedTableA T1
full outer join OrderedTableB T2 on T1.RowNum = T2.RowNum
Above query will create a new table as TableC with column col1 from TableA and col2 from TableB. You may change the queries to your need.
I hope you will understand the above queries. Give it a try.