Check if table is empty in SQLite - sql

I want to know if there is an better way to check if a table of a given database is empty.
My version:
import sqlite3
con = sqlite3.connect('emails.db')
cur = con.cursor()
cur.execute("SELECT count(*) FROM (select 1 from my_table limit 1);")
print(cur.fetchall()[0][0])
con.close()
Output:
0 # If table `my_table' is empty
1 # If table 'my_table' is not empty

Yo can use:
SELECT EXISTS (SELECT 1 FROM my_table);
this will return 1 row with 1 column which will be 0 if the table is empty or 1 if it contains any rows.
EXISTS will return as soon as it finds the 1st row in the table and it will not scan the whole table.

Related

select from table based on values not in lookup table from single record

I need to select from table A for a column value not in LKP table. The lookup table will have a list of values stored in a column in a single record.
Eg:
Table LKP will have something like this for a column C1 having value as 'INVALID','UNKNOWN' in a single record.
Table A:
ID
---
Bulbasaur
Charizard
Sqirtle
UNKNOWN
Ash
INVALID
Table LKP:
RULE C1
---- ---
1 'UNKNOWN','INVALID'
Desired output from below code:
select * from A where ID not in (select C1 from LKP where rule=1)
ID
---
Bulbasaur
Charizard
Sqirtle
Ash
I need to select all other values from table A except the one that are available in C1 as single record.The above code is not working. I am getting all the records returned from A. Should the record value for C1 be inserted differently in LKP table? It has to be in a single record mapped to rule=1 in where condition as shown.
Please suggest.
I discourage you from using not in with a subquery. If any of the returned values are NULL, then no rows at all are returned in the query.
Does not exists fix your problem?
select a.*
from A
where not exists (select 1 from LKP where lkp.rule = 1 and lkp.c1 = a.id);
You can split and explode the csv string and then do the comparison.
with split_values as (select rule,c1,c1_split
from LKP
lateral view explode(split(c1)) tbl as c1_split
)
select * from a
where not exists (select 1 from split_values s where s.c1_split=a.id and s.rule=1)

How to SQL Query records from Multiple that Equal 0?

I have a table that has multiple duplicate records in the first column (ID records), but has varying numerical data in the second column.
I want to be able to identify which ID records have 0 for all of their numerical records.
For example the table can look like:
ID Value
1 2
1 2
1 0
2 0
2 0
2 0
I would want to only identify ID 2 because all the values are equal to 0. I don't want ID 1 because there are values > 0
Sorry if this isn't formatted properly or confusing.
You might use "NOT IN":
SELECT DISTINCT Id
FROM table1
WHERE Id NOT IN (SELECT Id FROM table1 WHERE Value <> 0)
SELECT DISTINCT ID FROM TABLE
WHERE ID NOT IN (SELECT DISTINCT ID FROM TABLE WHERE VALUE <> 0)
This will take all ID in the table where there is not a row where the value is non-zero.
SELECT *
FROM table t1
WHERE NOT EXISTS (SELECT 1 FROM table t2 WHERE t2.ID = t1.id AND Value <> 0)
"Select all records whose ID is not in the set of records that have a non-zero Value."

How to update all columns at once in ORACLE without sepcifying the column name

How do I update all columns at once without specifying the column name.
Say I have table A
ID NAME AGE
21 MATT 45
Table B
ID NAME AGE
21 SCOTT 24
What I expect
update table A
set A.columns=B.columns
Basically I'm trying to sync two tables.
As far as I know, there are no ways to update the table column values without specifying column name. Your purpose is to make the table A has the same values of table B, then you can delete all rows from the table A, and copy the data to table A.
delete from A;
insert into A select * from B;
commit;
If you have some reasons only to use update statement, and there are lots of columns, then you can generate the update statement by using dictionary.
select 'A.'||column_name||'=B.'||column_name||','
from all_tab_columns
where owner = 'your schema name'
and table_name = 'A';
You execute the query and copy the result and edit.
update A
set <paste the result of previous query here>
;
You can do it in PLSQL:
for src in ( select * from B ) loop
update A set ROW = src where A.id = src.id;
end loop;
or for insert
for src in ( select * from B ) loop
insert into A values src;
end loop;

Postgresql Select rows and update column

I have SQL Select query with where clauses. For e.g
select * from table where status = 1
And how can I update single column with selected rows simultaneously while selecting? I want to mark selected rows, to avoid reselect on the next loop. Something like:
select * from table where status = 1; update table set proc = 1 where id in (select id from table where status = 1)
But this query will not return results.
Use the returning clause:
update table
set proc = 1
where id in (select id from table where status = 1)
returning *;
(Btw: I assume the inner select is not actually selecting from the same table, because then the statement does not really makes sense as it could be rewritten with a simple where stauts = 1)

Select rows and Update same rows for locking?

I need to write a procedure that will allow me to select x amount of rows and at the same time update those rows so the calling application will know those records are locked and in use. I have a column in the table named "locked". The next time the procedure is called it will only pull the next x amount of records that do not have the "locked" column checked. I have read a little about the OUTPUT method for SQL server, but not sure that is what I want to do.
As you suggested, you can use the OUTPUT clause effectively:
Live demo: https://data.stackexchange.com/stackoverflow/query/8058/so3319842
UPDATE #tbl
SET locked = 1
OUTPUT INSERTED.*
WHERE id IN (
SELECT TOP 1 id
FROM #tbl
WHERE locked = 0
ORDER BY id
)​
Also see this article:
http://www.sqlmag.com/article/tsql3/more-top-troubles-using-top-with-insert-update-and-delete.aspx
Vote for Cade Roux's answer, using OUTPUT:
UPDATE #tbl
SET locked = 1
OUTPUT INSERTED.*
WHERE id IN (SELECT TOP 1 id
FROM #tbl
WHERE locked = 0
ORDER BY id)​
Previously:
This is one of the few times I can think of using a temp table:
ALTER PROCEDURE temp_table_test
AS
BEGIN
SELECT TOP 5000 *
INTO #temp_test
FROM your_table
WHERE locked != 1
ORDER BY ?
UPDATE your_table
SET locked = 1
WHERE id IN (SELECT id FROM #temp_test)
SELECT *
FROM #temp_test
IF EXISTS (SELECT NULL
FROM tempdb.dbo.sysobjects
WHERE ID = OBJECT_ID(N'tempdb..#temp_test'))
BEGIN
DROP TABLE #temp_test
END
END
This:
Fetches the rows you want, stuffs them into a local temp table
Uses the temp table to update the rows to be "locked"
SELECTs from the temp table to give you your resultset output
Drops the temp table because they live for the session