insert row if one with equal value does not already exist - sqlite

I'm trying to do an insert into table if the table doesn't already contain a field with a specified value. For this I am using this command: INSERT INTO zyprexa (NULL,'hello',0,0,0) SELECT date WHERE NOT EXISTS (SELECT 1 FROM zyprexa WHERE date='hello'); so it should insert a row with the values null,'hello',0,0,0. And then if it is executed again it should not do anything since there is already a row with the date value "hello". But it gives me a syntax error and doesn't run it even the first time. All the best.

The correct syntax is:
INSERT INTO zyprexa (col1, col2, col3, col4, col5)
SELECT NULL, 'hello', 0, 0, 0
WHERE NOT EXISTS (SELECT 1 FROM zyprexa WHERE date = 'hello');
where col1, col2, col3, col4, col5 are the names of the columns that will receive the values (for example col2 should be date).
If you want the column date to be unique in your table, you should define it as such:
CREATE TABLE zyprexa (
......
date TEXT UNIQUE,
......
);
and then you can execute INSERT statements with INSERT OR IGNORE, in which case if you try to insert a new row with a date (or any other column defined as unique) that already exists in the table, the insertion will fail (without any error):
INSERT OR IGNORE INTO zyprexa (col1, col2, col3, col4, col5)
VALUES (NULL, 'hello', 0, 0, 0);

Related

check for null values in all columns of a table using SQLite

I have a table with more than 15 columns. 2 of of them are of the type varchar, and most of them of type int and float.
I am new to SQL and am trying to figure out a way by which I can check if any of the columns have a NULL value in it.
Had there been just 4 or 5 columns I could have checked them individually with
SELECT COUNT(*) FROM table_name WHERE col1 IS NULL OR col2 IS NULL OR col3 IS NULL ...
But is there any efficient way to do this on a lot of columns in SQLite specifically?
I have referred to other questions regarding this here but I cannot use xml or store anything. Also I am using SQLite and can only run a query.
There is no way (that I know of) to check all columns if they contain null without explicitly listing all the column names.
Your query is the proper way to do it.
If you want to shorten (not significantly) the code you could use these alternatives:
SELECT COUNT(*) FROM table_name WHERE col1 + col2 + col3 IS NULL;
or:
SELECT COUNT(*) FROM table_name WHERE col1 || col2 || col3 IS NULL;
or:
SELECT COUNT(*) FROM table_name WHERE MAX(col1, col2, col3) IS NULL;
The above queries work, for any data type of the columns, because if there is even only 1 column equal to null then addition, concatenation and the scalar function MAX() (and MIN()) all return null.
See the demo.

How do I compare two columns from two different tables

I am running a CREATE TABLE TBL AS SELECT statement as below. I want to write a CASE STATEMENT that will compare
values from column X.PRESC_ID to values from column Y.PRSC_NPI and if there is match, it should INSERT to TBL.PRESC_ID,
and for all the X.PRESC_ID that do not match with any value in Y.PRSC_NPI should be INSERTED to TBL.PRSC_NPI_N
CREATE TABLE TBL (
Col1,
Col2,
PRESC_ID,
PRSC_NPI_N,
AS
(
SELECT
Col1,
Col2,
PRESC_ID,
PRSC_NPI_N,
FROM TBL2 X
JOIN
(SELECT CLAIM_ID,PRSC_NPI FROM TBL3) Y
ON Y.CLAIM_ID = Y.Col1
I have tried the one below but it is not working
CASE
WHEN X.PRESC_ID = Y.PRSC_NPI THEN TBL.PRESC_ID
ELSE TBL.PRSC_NPI_N
END
Seems you really want two CASE expressions, one for each result column. Something like
CASE WHEN X.PRESC_ID = Y.PRSC_NPI THEN X.PRESC_ID END AS PRESC_ID,
CASE WHEN NOT(X.PRESC_ID = Y.PRSC_NPI) THEN X.PRSC_NPI_N END AS PRSC_NPI_N

how to insert but get data from multiple tables

I have a simple SQL insert query, however two of the data entires come from two other tables,
I know how to get data from from one table in an insert but how do i get data from two tables?
Example (One Table Data)
INSERT INTO TABLE (COL1, COL2, COL3)
SELECT :COL1, :COL2, TABLE2.ID
FROM TABLE2
WHERE TABLE2.NAME = :LEVEL0
The above works fine and pulls relevant data out of table2, issue is i need to add a third table.
INSERT INTO TABLE (COL1, COL2, COL3, COL4)
SELECT :COL1,
:COL2,
(TABLE2.ID FROM TABLE2 WHERE TABLE2.NAME = :LEVEL0),
(TABLE3.ID FROM TABLE3 WHERE TABLE3.NAME = :LEVEL1)
doesn't work i get SQL errors
Subqueries are queries, so they need their own SELECT:
INSERT INTO TABLE (COL1, COL2, COL3, COL4)
SELECT :COL1,
:COL2,
(SELECT ID FROM TABLE2 WHERE NAME = :LEVEL0),
(SELECT ID FROM TABLE3 WHERE NAME = :LEVEL1);
And when all values are computed by subqueries, you do not need to use the SELECT form of the INSERT:
INSERT INTO TABLE (COL1, COL2, COL3, COL4)
VALUES(:COL1,
:COL2,
(SELECT ID FROM TABLE2 WHERE NAME = :LEVEL0),
(SELECT ID FROM TABLE3 WHERE NAME = :LEVEL1));
Literally as i asked the question i found the solution 'cross join'
INSERT INTO TABLE1 (COL1, COL2, COL3, COL4)
SELECT :COL1, :COL2, TABLE2.ID, TABLE3.ID
FROM TABLE2 CROSS JOIN TABLE3
WHERE TABLE2.NAME = :LEVEL0 AND TABLE3.NAME = :LEVEL1

Insert multiple rows into 1 table for each row in another table

I have a temp table that I want to use to populate another table. For every row in the temp table I want to execute a function that may result in one or more records being generated for the other table.
DECLARE
CURSOR cur IS SELECT col1, col2, col3 FROM table1;
BEGIN
FOR rec
IN cur
LOOP
-- Pseudo Code Follows
FOR result
IN somefunction(rec.col1, rec.col2)
INSERT INTO table2
(col1, col2, col3, calculated_value)
VALUES
(rec.col1, rec.col2, rec.col3, result.calculated_value)
END LOOP;
END LOOP;
END;
Does this make sense to do it this way?
Can Oracle PL/SQL functions return something iterable like this?
I would normally do this in Perl or Python, but since all the data is in Oracle, I don't want to waste time retrieving the data, calculating it, and then inserting the data, if it can all be done within the database. The temp table will have about 75000 rows, and I expect the second table will have 550000 rows.
Create Temporary table in Oracle for one time only (ONCE and only ONCE not every session)
The rows you insert into it are visible only to your session, and are automatically deleted when you end you session ( or end of the transaction, depending on which "ON COMMIT" clause you use).
Example:
CREATE GLOBAL TEMPORARY TABLE temp_table
(col1 number,
col2 DATE,
col3 varchar2(20)
) ON COMMIT DELETE ROWS;
Now comming to your case:
CURSOR C
IS
SELECT col1, col2, col3 FROM temp_table;
X_calculated_value VARCHAR2 (1000);
BEGIN
--Your temporary table should be filled in the session
FOR I IN C
LOOP
select somefunction(I.col1, I.col2) into X_calculated_value from dual;
IF calculated_value ..YourCodition
THEN
INSERT INTO table2
(col1, col2, col3, calculated_value)
VALUES
(I.col1, I.col2, I.col3, X_calculated_value)
ELSE
//do something also
END IF;
END LOOP;
END;

SQLITE equivalent for Oracle's ROWNUM?

I'm adding an 'index' column to a table in SQLite3 to allow the users to easily reorder the data, by renaming the old database and creating a new one in its place with the extra columns.
The problem I have is that I need to give each row a unique number in the 'index' column when I INSERT...SELECT the old values.
A search I did turned up a useful term in Oracle called ROWNUM, but SQLite3 doesn't have that. Is there something equivalent in SQLite?
You can use one of the special row names ROWID, OID or _ROWID_ to get the rowid of a column. See http://www.sqlite.org/lang_createtable.html#rowid for further details (and that the rows can be hidden by normal columns called ROWID and so on).
Many people here seems to mix up ROWNUM with ROWID. They are not the same concept and Oracle has both.
ROWID is a unique ID of a database ROW. It's almost invariant (changed during import/export but it is the same across different SQL queries).
ROWNUM is a calculated field corresponding to the row number in the query result. It's always 1 for the first row, 2 for the second, and so on. It is absolutely not linked to any table row and the same table row could have very different rownums depending of how it is queried.
Sqlite has a ROWID but no ROWNUM. The only equivalent I found is ROW_NUMBER() function (see http://www.sqlitetutorial.net/sqlite-window-functions/sqlite-row_number/).
You can achieve what you want with a query like this:
insert into new
select *, row_number() over ()
from old;
No SQLite doesn't have a direct equivalent to Oracle's ROWNUM.
If I understand your requirement correctly, you should be able to add a numbered column based on ordering of the old table this way:
create table old (col1, col2);
insert into old values
('d', 3),
('s', 3),
('d', 1),
('w', 45),
('b', 5465),
('w', 3),
('b', 23);
create table new (colPK INTEGER PRIMARY KEY AUTOINCREMENT, col1, col2);
insert into new select NULL, col1, col2 from old order by col1, col2;
The new table contains:
.headers on
.mode column
select * from new;
colPK col1 col2
---------- ---------- ----------
1 b 23
2 b 5465
3 d 1
4 d 3
5 s 3
6 w 3
7 w 45
The AUTOINCREMENT does what its name suggests: each additional row has the previous' value incremented by 1.
I believe you want to use the constrain LIMIT in SQLite.
SELECT * FROM TABLE can return thousands of records.
However, you can constrain this by adding the LIMIT keyword.
SELECT * FROM TABLE LIMIT 5;
Will return the first 5 records from the table returned in you query - if available
use this code For create Row_num 0....count_row
SELECT (SELECT COUNT(*)
FROM main AS t2
WHERE t2.col1 < t1.col1) + (SELECT COUNT(*)
FROM main AS t3
WHERE t3.col1 = t1.col1 AND t3.col1 < t1.col1) AS rowNum, * FROM Table_name t1 WHERE rowNum=0 ORDER BY t1.col1 ASC

Resources