I want to insert records from first table to second in such a way that only unique records get inserted. That is if table one and two has overlapping (duplicate) records, only the unique records get inserted into table one from table two. For example I have one table named Table_One,
and another table named Table_Two,
now I want to add the records from Table_Two the records that are not already in Table_one which is (XYZ | UVW) so that the output is,
I tried using this technique,
INSERT INTO TableB(Col1, Col2, Col3, ... , Coln)
SELECT DISTINCT A.Col1, A.Col2, A.Col3, ... , A.Coln
FROM TableA A
LEFT JOIN TableB B
ON A.KeyOfTableA = B.KeyOfTableB
WHERE B.KeyOfTableB IS NULL
but the duplicate rows also got inserted, any suggestions as to what could be the solution ??? I am using sqlite3 db.
INSERT INTO TableB (Col1, Col2, Col3, ... , Coln)
SELECT DISTINCT A.Col1,
A.Col2,
A.Col3,
... ,
A.Coln
FROM TableA A
WHERE A.KeyOfTableA NOT IN (SELECT B.KeyOfTableB
FROM TableB B)
Simply use UNION.
Query
sqlite> CREATE TABLE table1(firstName VARCHAR(50),lastName VARCHAR(50));
sqlite> INSERT INTO table1 VALUES('ABC','DEF');
sqlite> INSERT INTO table1 VALUES('GHI','JKL');
sqlite> INSERT INTO table1 VALUES('MNO','PQR');
sqlite>
sqlite> CREATE TABLE table2(first VARCHAR(50),last VARCHAR(50));
sqlite> INSERT INTO table2 VALUES('ABC','DEF');
sqlite> INSERT INTO table2 VALUES('XYZ','UVW');
sqlite> .headers ON
sqlite> SELECT * FROM table1 UNION SELECT * FROm table2;
OUTPUT
firstName|lastName
ABC|DEF
GHI|JKL
MNO|PQR
XYZ|UVW
Related
In Sqlite, I defined a view as a union all of two tables. When I run queries using that view, the index is used if the query is simple enough. For certain complex queries, it does not and ends up running full table scans. Are there ways around this so that I can use views performantly?
Table/View Definitions:
CREATE TABLE 'Table1' (Id varchar (18) PRIMARY KEY UNIQUE ON CONFLICT ROLLBACK, Name varchar (255) )
CREATE TABLE 'Table2' (Id varchar (18) PRIMARY KEY UNIQUE ON CONFLICT ROLLBACK, Name varchar (255) )
CREATE TABLE 'Table3' (Id varchar (18) PRIMARY KEY UNIQUE ON CONFLICT ROLLBACK, Name varchar (255) )
CREATE VIEW [UnionView] AS SELECT 'T1' tid, T1.rowid, T1.* FROM [Table1] T1 UNION ALL SELECT 'T2' tid, T2.rowid, T2.* FROM [Table2] T2
Simple Query (indexes are used):
SELECT Id FROM [UnionView] WHERE Id = 'asdf'
Explain Query Plan:
COMPOUND QUERY
LEFT-MOST SUBQUERY
SEARCH TABLE Table1 AS T1 USING INDEX sqlite_autoindex_Table1_1 (Id=?)
UNION ALL
SEARCH TABLE Table2 AS T2 USING INDEX sqlite_autoindex_Table2_1 (Id=?)
LEFT JOIN Query (indexes are not used):
SELECT T3.Id FROM [Table3] T3 LEFT JOIN [UnionView] T ON T3.Id=T.Id WHERE T3.Id = 'asdf'
Explain Query Plan
MATERIALIZE 2
COMPOUND QUERY
LEFT-MOST SUBQUERY
SCAN TABLE Table1 AS T1
UNION ALL
SCAN TABLE Table2 AS T2
SEARCH TABLE Table3 AS T3 USING COVERING INDEX sqlite_autoindex_Table3_1 (Id=?)
SCAN SUBQUERY 2 AS T
Your complex query does full table scans of Table1 and Table2 because you are not doing any filtering on UnionView.
It does use though sqlite_autoindex_Table3_1.
Also, the WHERE clause is applied after the joins.
If you filter UnionView before the join then indexes will be used:
EXPLAIN QUERY PLAN
SELECT T3.Id
FROM [Table3] T3
LEFT JOIN (SELECT Id FROM [UnionView] WHERE Id = 'asdf') T
ON T3.Id=T.Id
WHERE T3.Id = 'asdf'
Result:
MATERIALIZE 3
COMPOUND QUERY
LEFT-MOST SUBQUERY
SEARCH TABLE Table1 AS T1 USING INDEX sqlite_autoindex_Table1_1 (Id=?)
UNION ALL
SEARCH TABLE Table2 AS T2 USING INDEX sqlite_autoindex_Table2_1 (Id=?)
SEARCH TABLE Table3 AS T3 USING COVERING INDEX sqlite_autoindex_Table3_1 (Id=?)
SCAN SUBQUERY 3
Do you know how to create an Oracle query that will list my table name, followed by all the column names in that table? I have 5 tables in total.
Something like:
Table
Column1
Column2
Column3
Table2
Column1
Table3
Column1
Column2
I'm hard-pressed to imagine why you would want a single-column result that doesn't do anything to differentiate between what is a column name and what is a table name. You can do something like
select pseudo_column_name
from (
select table_name, table_name pseudo_column_name, 0 column_id
from user_tables
union all
select table_name, column_name, column_id
from user_tab_columns
)
order by table_name, column_id
I am having two tables which i wish to join.
I am not using foreign keys.
table structure table1
id,val1
table structure table2
id,val2
I am using now following command:
update table1 set val1=(SELECT val2 FROM table2 WHERE table1.id LIKE table2.id)
How can i force sqlite not to insert a value in table1 if an id does not exist in table2?
To use exact comparisons, use = instead of LIKE.
To update only those rows where a match is found, use a WHERE clause:
UPDATE Table1
SET val1 = (SELECT val2
FROM Table2
WHERE Table1.id = Table2.id)
WHERE id IN (SELECT id FROM Table2);
If you omit the WHERE clause, rows without a match get updated with a NULL value.
C:\Users\pengsir>sqlite3 e:\\test.db
sqlite> create table test (f1 TEXT,f2 TEXT, f3 TEXT);
sqlite> insert into test values("x1","y1","w1");
sqlite> insert into test values("x1","y1","w2");
sqlite> insert into test values("x1","y3","w2");
sqlite> insert into test values("x2","y3","w2");
sqlite> insert into test values("x3","y4","w4");
sqlite> insert into test values("x2","y3","w4");
sqlite> insert into test values("x1","y3","w2");
sqlite>
1.select the record rows which contain the same f1 and f2 ,and the rowid .
sqlite> select rowid,f1,f2 from test group by f1,f2 having(count(f2)>1 and count(f2)>1);
2|x1|y1
7|x1|y3
6|x2|y3
I want the result to be :
1|x1|y1
2|x1|y1
3|x1|y3
4|x2|y3
6|x2|y3
7|x1|y3
2.select the record rows which contain the same f1 f2 and f3,and the rowid .
sqlite> select rowid,f1,f2,f3 from test group by f1,f2,f3 having(count(f2)>1 and count(f3)>1);
7|x1|y3|w2
I want the result to be
3|x1|y3|w2
7|x1|y3|w2
let us discuss this problem further , i want to delete one |x1|y3|w2 and keep one |x1|y3|w2 in the table?here is my method.
DELETE FROM test
WHERE rowid in(
SELECT rowid FROM test
WHERE (SELECT count(*)
FROM test AS t2
WHERE t2.f1 = test.f1
AND t2.f2 = test.f2
AND t2.f3 = test.f3
) >= 2 limit 1);
Is there more simple and smart way to do that? (the method is wrong)
I find the proper way to do .
delete from test
where rowid not in
(
select max(rowid)
from test
group by
f1,f2,f3
);
and the method to more than one duplicate for a f1/f2 combination is :
delete from test
where rowid not in
(select rowid from test group by f1,f2);
It will be executed only one time.
You want records that have duplicates (in those fields), i.e., where the number of records with the same values in those fields is at least two:
SELECT rowid, f1, f2
FROM test
WHERE (SELECT count(*)
FROM test AS t2
WHERE t2.f1 = test.f1
AND t2.f2 = test.f2
) >= 2
This requires executing the subquery for each record.
Alternatively, compute the records with duplicates in a subquery once; this might be more efficient:
SELECT test.rowid, test.f1, test.f2
FROM test
JOIN (SELECT f1, f2
FROM test
GROUP BY f1, f2
HAVING count(*) >= 2
) USING (f1, f2)
If you want to remove one of the duplicates, this is easier to do because GROUP BY already returns exactly one output row for each group:
DELETE FROM test
WHERE rowid IN (SELECT max(rowid)
FROM test
GROUP BY f1, f2
HAVING COUNT(*) >= 2)
(If there is more than one duplicate for a f1/f2 combination, you have to execute this multiple times.)
Try using SELECT ALL instead of SELECT but according to the linked docs SELECT should behave like SELECT ALL by default and not like SELECT DISTINCT so I don't know where the problem may be.
I am trying to update a selected values in a column in a SQLite table. I only want update of the cells in the maintable where the criteria are met, and the cells must be updated to individual values, taken from a subtable.
I have tried the following syntax, but I get only a single cell update. I have also tried alternatives where all cells are updated to the first selected value of the subtable.
UPDATE maintable
SET value=(SELECT subtable.value FROM maintable, subtable
WHERE maintable.key1=subtable.key1 AND maintable.key2=subtable.key2)
WHERE EXISTS (SELECT subtable.value FROM maintable, subtable
WHERE maintable.key1=subtable.key1 AND maintable.key2=subtable.key2)
What is the appropriate syntax?
You can do this with an update select, but you can only do one field at a time. It would be nice if Sqlite supported joins on an update statement, but it does not.
Here is a related SO question, How do I UPDATE from a SELECT in SQL Server?, but for SQL Server. There are similar answers there.
sqlite> create table t1 (id int, value1 int);
sqlite> insert into t1 values (1,0),(2,0);
sqlite> select * from t1;
1|0
2|0
sqlite> create table t2 (id int, value2 int);
sqlite> insert into t2 values (1,101),(2,102);
sqlite> update t1 set value1 = (select value2 from t2 where t2.id = t1.id) where t1.value1 = 0;
sqlite> select * from t1;
1|101
2|102
In this case, it only updates one value from subtable per each raw from maintable.
The error is when subtable is include into of SELECT sentence.
UPDATE maintable
SET value=(SELECT subtable.value
FROM subtable
WHERE maintable.key1=subtable.key1 );
By default update with joins does not exist in SQLite; But we can use the with-clause + column-name-list + select-stmt from https://www.sqlite.org/lang_update.html to make something like this:
CREATE TABLE aa (
_id INTEGER PRIMARY KEY,
a1 INTEGER,
a2 INTEGER);
INSERT INTO aa VALUES (1,10,20);
INSERT INTO aa VALUES (2,-10,-20);
INSERT INTO aa VALUES (3,0,0);
--a bit unpleasant because we have to select manually each column and it's just a lot to write
WITH bb (_id,b1, b2)
AS (SELECT _id,a1+2, a2+1 FROM aa WHERE _id<=2)
UPDATE aa SET a1=(SELECT b1 FROM bb WHERE bb._id=aa._id),a2=(SELECT b2 FROM bb WHERE bb._id=aa._id)
WHERE _id in (SELECT _id from bb);
--soo now it should be (1,10,20)->(1,12,21) and (2,-10,-20)->(2,-8,-19), and it is
SELECT * FROM aa;
--even better with one select for each row!
WITH bb (_id,b1, b2)
AS (SELECT _id,a1+2, a2+1 from aa WHERE _id<=2)
UPDATE aa SET (a1,a2)=(SELECT b1,b2 FROM bb WHERE bb._id=aa._id)
WHERE _id in (SELECT _id from bb);
--soo now it should be (1,12,21)->(1,14,22) and (2,-8,-19)->(2,-6,-18), and it is
SELECT * FROM aa;
--you can skip the WITH altogether
UPDATE aa SET (a1,a2)=(SELECT bb.a1+2, bb.a2+1 FROM aa AS bb WHERE aa._id=bb._id)
WHERE _id<=2;
--soo now it should be (1,14,22)->(1,16,23) and (2,-6,-18)->(2,-4,-17), and it is
SELECT * FROM aa;
Hopefully sqlite is smart enough to not query incrementally but according to the documentation it is. When setting multiple columns using one select (case 2 and 3) a not valid id (no where _id in line) will give an error that can not be ignored using ON IGNORE, case 1 will set columns to null (for all ids >2) which is also bad.
You need to use an INSERT OR REPLACE statement, something like the following:
Assume maintable has 4 columns: key, col2, col3, col4
and you want to update col3 with the matching value from subtable
INSERT OR REPLACE INTO maintable
SELECT maintable.key, maintable.col2, subtable.value, maintable.col4
FROM maintable
JOIN subtable ON subtable.key = maintable.key