Need some help on writing SQL query - oracle11g

Hope you are doing good. I am new to SQL coding. I want to write a query which finds the difference between two tables and writes updates or new data into third table. My two tables have identical column names. Third table which captures changes have extra column called comment. I would like to insert the comment whether it is a new row or updated row based on the row modification.
**TABLE1 (BACKUP)**
KEY,FIRST_NAME,LAST_NAME,CITY
1,RAM,KUMAR,INDIA
2,TOM,MOODY,ENGLAND
3,MOHAMMAD,HAFEEZ,PAKISTAN
4,MONIKA,SAM,USA
5,MIKE,PALEDINO,USA
**TABLE2 (CURRENT)**
KEY,FIRST_NAME,LAST_NAME,CITY
1,RAM,KUMAR,USA
2,TOM,MOODY,ENGLAND
3,MOHAMMAD,HAFEEZ,PAKISTAN
4,MONIKA,SAM,INDIA
5,MIKE,PALEDINO,USA
6,MAHELA,JAYA,SL
**TABLE3 (DIFFERENCE FROM TABLE2 TO TABLE1)**
KEY,FIRST_NAME,LAST_NAME,CITY,COMMENT
1,RAM,KUMAR,USA,UPDATE
4,MONIKA,SAM,INDIA,UPDATE
6,MAHELA,JAYA,SL,INSERT
Anyone else? I want to update my comments columns whether it is a new insert or update to existing row

#danny117 is correct in the general sense though I think using MINUS is better
SELECT * FROM TABLE2
MINUS
SELECT * FROM TABLE1
You may also like to look at this documentation which explains more about minus, intersect

INSERT INTO TABLE3
SELECT KEY,FIRST_NAME,LAST_NAME,CITY,NULL AS COMMENTS FROM TABLE2
MINUS
SELECT KEY,FIRST_NAME,LAST_NAME,CITY,NULL AS COMMENTS FROM TABLE1;
UPDATE TABLE3
SET COMMENTS =
CASE
WHEN 1=(SELECT 1 FROM TABLE1 WHERE TABLE1.KEY=TABLE3.KEY) THEN 'UPDATED'
ELSE 'INSERTED'
END

Related

update (overwrite) an entire record (all columns) in sqlite

When I am copying rows from one table to another, there is a convenient syntax:
INSERT INTO table1 SELECT * FROM table2 WHERE <table 2 rows have some property>
But what if I want to overwrite entire existing rows in table1 with entire rows from table2? So I want something like:
UPDATE table1 SET * FROM table2 WHERE <table 1 and 2 rows match on some key field>
But from what I can tell, the only way to do this is to enumerate the columns being set one by one (set table1.columnA = table2.columnA, table1.columnB = table2.columnB, and so on). Is there some way to say "do it for all the columns" when using UPDATE like there is when using INSERT? If not, why not?
(I guess I could delete all rows from table1 with the given property, and then use the INSERT INTO table1 SELECT * syntax to bring in the replacement rows from table2. But that seems like it leaves a bunch of unwanted deleted rows in the database needing to be vacuumed at some point, as opposed to a clean UPDATE where there are no deleted records? Or maybe I'm not understanding the efficiency of a bunch of deletes followed by a bunch of inserts?)
There is no such syntax for exactly what you have in mind, and I think you will need to SET each column separately. Also, SQLite does not support a direct update join syntax, but we may use correlated subqueries:
UPDATE table1
SET table1.columnA = (SELECT columnA FROM table2 WHERE table1.col = table2.col),
SET table1.columnB = (SELECT columnB FROM table2 WHERE table1.col = table2.col),
SET table1.columnC = (SELECT columnC FROM table2 WHERE table1.col = table2.col);

SQLite: How to UPDATE column using count(*) range?

I'm not sure I'm using right terminology here.
Basically I want to update entire "id" column using count(*) [485] as a delimiter, in an ascending order, so the resulting row value will correspond with rownumber (not the rowid).
If I understand you correctly, this should work for you:
UPDATE tbl_name SET id=rowid
EDIT
If that's is the case -> then it's a lit bit more tricky, since SQlite doesn't support variables declaration.
So what I suggest is,
To create temporary table from select of your original table which makes it's rowids to be as row numbers 1,2,3 etc...
Set it's rowNum (the needed row number column) as each rowid
Then replace the original table with it.
Like this: (assume original table called orig_name)
CREATE TABLE tmp_tbl AS SELECT rowNum FROM orig_name;
UPDATE tmp_tbl SET rowNum=rowid;
DROP TABLE orig_name;
CREATE TABLE orig_name AS SELECT rowNum FROM tmp_tbl;
DROP TABLE tmp_tbl;
Try this: http://www.sqlite.org/lang_createtable.html#rowid
You can use some inner database variables such as rowid, oid etc to get what you need.
[edit]
Think I just understood what you meant, you want for each insert action, add a value that is the total count of rows currently in the table?
If so, try something like this:
UPDATE tbl_name
SET id = (select count(*) from tbl_name)
WHERE yada_yada_yada

select * from (select...) sqlite python

I'm working on a sqlite database and try to make a special request between two tables.
In the first table (table1 for example), i have two columns named "reference" and "ID". I want to search an ID in it, get it value in "reference" and display all informations from the table which have this value as name.
I try to find something on the internet but I didn't find an answer.
This is the request I made:
select * from (select Reference from table1 where Name='Value1')
It only give me the result of
select Reference from table1 where Name='Value1'
EDIT:
I want
select Reference from table1 where Name='Value1' => name of table
select * from name of table => show all elements
I'm new in sqlite but I hope you can help me.
Thank you by advance
Matt
If I understand your question correctly, I don't think there's a way to do it in sql completely (or at least not in a portable way). I'd recommend one of 3 solutions:
Do exactly what you want, but do some processing in Python. That means query your master table, then construct new query based on each of the rows returned.
If you have many tables, possibly changing dynamically - it may be a good idea to rethink your database design. Maybe you can move some of the changing table names into a new column and put your data in one table?
If you have only a few tables available as the Reference and they never change, you could join all the possible tables, like:
SELECT ... FROM table1
LEFT JOIN table2
ON table1.id = table2.id AND table1.Reference = "table2"
LEFT JOIN table3 ...
But you may need to explain it all a bit better...

How can I insert a new table row into every other row in an existing table?

Ok I have a sqlite db, that has roughly 100 rows. It is kind of a strange thing that I'm trying to do, but I need to insert a new row between each of the existing rows.
I have been trying to use the Insert statement as follows, but haven't had any luck:
insert into t1(column1) values("hello") where id%2 == 0
So I'm basically trying to use the %-operator to tell me if the id is even or odd. For every even id number, I'd like to insert a new row.
What am I missing? What can I do differently? How can I insert a new row into every other row and have the index updated as well?
Thanks
Your question assumes that the rows have some kind of built-in order to them, and that you can insert rows between other rows. That's not true.
It is true that rows have an order on disk, and that the id column is usually assigned in order, but that's an implementation detail. When you perform a query, the database is free to return the rows in any order it chooses, unless you specify what you want with an ORDER BY clause.
Now, I'm assuming what you really want is to insert rows between the existing rows in id order. One way to get what you want would look like this:
UPDATE t1 SET id = id * 2
INSERT INTO t1 (id, column) SELECT id+1, "hello" FROM t1
The UPDATE would double the ids of all the existing rows (so 1,2,3 becomes 2,4,6); then the INSERT would perform a query on t1 and use the result to insert a new set of rows with id values one more than the existing rows (so 2,4,6 becomes 3,5,7).
I haven't tested the above statements, so I don't know if they would work or if they require some extra trickery (like a temporary table) since we are querying and updating the same table in one statement. Also I may have made a syntax error.
Don't consider the rows as pre-ordered in the database. A database will store them as they come in, or according to an index. It's your task to order them on retrieval (i.e. when you query for data) according to your needs.

How to get the number of rows of the selected result from sqlite3?

I want to get the number of selected rows as well as the selected data. At the present I have to use two sql statements:
one is
select * from XXX where XXX;
the other is
select count(*) from XXX where XXX;
Can it be realised with a single sql string?
I've checked the source code of sqlite3, and I found the function of sqlite3_changes(). But the function is only useful when the database is changed (after insert, delete or update).
Can anyone help me with this problem? Thank you very much!
SQL can't mix single-row (counting) and multi-row results (selecting data from your tables). This is a common problem with returning huge amounts of data. Here are some tips how to handle this:
Read the first N rows and tell the user "more than N rows available". Not very precise but often good enough. If you keep the cursor open, you can fetch more data when the user hits the bottom of the view (Google Reader does this)
Instead of selecting the data directly, first copy it into a temporary table. The INSERT statement will return the number of rows copied. Later, you can use the data in the temporary table to display the data. You can add a "row number" to this temporary table to make paging more simple.
Fetch the data in a background thread. This allows the user to use your application while the data grid or table fills with more data.
try this way
select (select count() from XXX) as count, *
from XXX;
select (select COUNT(0)
from xxx t1
where t1.b <= t2.b
) as 'Row Number', b from xxx t2 ORDER BY b;
just try this.
You could combine them into a single statement:
select count(*), * from XXX where XXX
or
select count(*) as MYCOUNT, * from XXX where XXX
To get the number of unique titles, you need to pass the DISTINCT clause to the COUNT function as the following statement:
SELECT
COUNT(DISTINCT column_name)
FROM
'table_name';
Source: http://www.sqlitetutorial.net/sqlite-count-function/
For those who are still looking for another method, the more elegant one I found to get the total of row was to use a CTE.
this ensure that the count is only calculated once :
WITH cnt(total) as (SELECT COUNT(*) from xxx) select * from xxx,cnt
the only drawback is if a WHERE clause is needed, it should be applied in both main query and CTE query.
In the first comment, Alttag said that there is no issue to run 2 queries. I don't agree with that unless both are part of a unique transaction. If not, the source table can be altered between the 2 queries by any INSERT or DELETE from another thread/process. In such case, the count value might be wrong.
Once you already have the select * from XXX results, you can just find the array length in your program right?
If you use sqlite3_get_table instead of prepare/step/finalize you will get all the results at once in an array ("result table"), including the numbers and names of columns, and the number of rows. Then you should free the result with sqlite3_free_table
int rows_count = 0;
while (sqlite3_step(stmt) == SQLITE_ROW)
{
rows_count++;
}
// The rows_count is available for use
sqlite3_reset(stmt); // reset the stmt for use it again
while (sqlite3_step(stmt) == SQLITE_ROW)
{
// your code in the query result
}

Resources