How do I make an UPDATE while joining tables on SQLite? - sqlite

I tried :
UPDATE closure JOIN item ON ( item_id = id )
SET checked = 0
WHERE ancestor_id = 1
And:
UPDATE closure, item
SET checked = 0
WHERE ancestor_id = 1 AND item_id = id
Both works with MySQL, but those give me a syntax error in SQLite.
How can I make this UPDATE / JOIN works with SQLite version 3.5.9 ?

You can't. SQLite doesn't support JOINs in UPDATE statements.
But, you can probably do this with a subquery instead:
UPDATE closure SET checked = 0
WHERE item_id IN (SELECT id FROM item WHERE ancestor_id = 1);
Or something like that; it's not clear exactly what your schema is.

You can also use REPLACE then you can use selection with joins.
Like this:
REPLACE INTO closure
SELECT sel.col1,sel.col2,....,sel.checked --checked should correspond to column that you want to change
FROM (
SELECT *,0 as checked FROM closure LEFT JOIN item ON (item_id = id)
WHERE ancestor_id = 1) sel

Related

Oracle - Updating with Join 3 tables

I have 3 tables: inventory as table 1, buy_transaction as table 2, and po_data as table 3.
These are the queries I tried:
update vnt_inventory_tab.quantity
set vnt_inventory_tab.quantity = quantity + (SELECT pdt.quantity
FROM vnt_po_data_tab pdt JOIN vnt_buy_trnsctn_tab bt ON pdt.po_no = bt.po_no
WHERE pdt.po_no = :p_po_no)
where VNT_INVENTORY_TAB.CODE = VNT_PO_DATA_TAB.CODE;
It return as table doesn't exist. I'm not sure where I put wrong because when I do the sub-query it returns exactly the number I want to update into the inventory.
Help me pls
Syntax UPDATE statement requires only table-Name (not a specific column like yours) after the keyword update. More details see Oracle docs

Update row with value from next row sqlite

I have the following columns in a SQLite DB.
id,ts,origin,product,bid,ask,nextts
1,2016-10-18 20:20:54.733,SourceA,Dow,1.09812,1.0982,
2,2016-10-18 20:20:55.093,SourceB,Oil,7010.5,7011.5,
3,2016-10-18 20:20:55.149,SourceA,Dow,18159.0,18161.0,
How can I populate the 'next timestamp' column (nextts) with the next timestamp for the same product (ts), from the same source? I've been trying the following, but I can't seem to put a subquery in an UPDATE statement.
UPDATE TEST a SET nextts = (select ts
from TEST b
where b.id> a.id and a.origin = b.origin and a.product = b.product
order by id asc limit 1);
If I call this, I can display it, but I haven't found a way of updating the value yet.
select a.*,
(select ts
from TEST b
where b.id> a.id and a.origin = b.origin and a.product = b.product
order by id asc limit 1) as nextts
from TEST a
order by origin, a.id;
The problem is that you're using table alias for table in UPDATE statement, which is not allowed. You can skip alias from there and use unaliased (but table-name prefixed) reference to its columns (while keeping aliased references for the SELECT), like this:
UPDATE TEST
SET nextts = (
SELECT b.ts
FROM TEST b
WHERE b.id > TEST.id AND
TEST.origin = b.origin AND
TEST.product = b.product
ORDER BY b.id ASC
LIMIT 1
);
Prefixing unaliased column references with the table name is necessary for SQLite to identify that you're referencing to unaliased table. Otherwise the id column whould be understood as the id from the closest[*] possible data source, in which case it's the aliased table (as b alias), while we're interested in the unaliased table, therefore we need to explicitly tell SQLite that.
[*] Closest data source is the one listed in the same query, or parent query, or parent's parent query, etc. SQLite is looking for the first data source (going from inner part to the outside) in the query hierarchy that defines this column.

sqlite manager lookup table [duplicate]

I tried :
UPDATE closure JOIN item ON ( item_id = id )
SET checked = 0
WHERE ancestor_id = 1
And:
UPDATE closure, item
SET checked = 0
WHERE ancestor_id = 1 AND item_id = id
Both works with MySQL, but those give me a syntax error in SQLite.
How can I make this UPDATE / JOIN works with SQLite version 3.5.9 ?
You can't. SQLite doesn't support JOINs in UPDATE statements.
But, you can probably do this with a subquery instead:
UPDATE closure SET checked = 0
WHERE item_id IN (SELECT id FROM item WHERE ancestor_id = 1);
Or something like that; it's not clear exactly what your schema is.
You can also use REPLACE then you can use selection with joins.
Like this:
REPLACE INTO closure
SELECT sel.col1,sel.col2,....,sel.checked --checked should correspond to column that you want to change
FROM (
SELECT *,0 as checked FROM closure LEFT JOIN item ON (item_id = id)
WHERE ancestor_id = 1) sel

Sqlite select default rows if not exists

Sorry to pester with a simple problem but I'm stumped with a simple select on an HTML5 WebSQL Data Base.
Table tPhones has id, hid, location and several other columns. I would like to return a list of rows with where hid = [input value] or, if no rows with that hid exist, return rows where hid = 1.
I have tried LIMIT 1 ACS etc but that too fails.
Function showPhones(){
var phonegroup = $(this).attr("id");
var hid = localStorage.hid;
db.transaction (function(transaction)
{
var sql = "SELECT * FROM tPhones WHERE dept ='"+phonegroup+"' AND ((hid ='"+hid+"') OR IFNULL (hid ='1')) ORDER BY location ASC";
transaction.executeSql (sql, undefined,function(transaction,result)
{…………..rest of function working fine
Any help would be much appreciated.
A normal expression in the WHERE clause can access only columns of the current record.
To check for the existence of any other record, you have to use a subquery:
SELECT *
FROM tPhones
WHERE dept = ?
AND (hid = ? OR (hid = 1 AND
NOT EXISTS (SELECT 1
FROM tPhones
WHERE dept = ?
AND hid = ?)))
ORDER BY location

Is it possible to use WHERE clause in same query as PARTITION BY?

I need to write SQL that keeps only the minimum 5 records per each identifiable record in a table. For this, I use partition by and delete all records where the value returned is greater than 5. When I attempt to use the WHERE clause in the same query as the partition by statement, I get the error "Ordered Analytical Functions not allowed in WHERE Clause". So, in order to get it to work, I have to use three subqueries. My SQL looks ilke this:
delete mydb.mytable where (field1,field2) in
(
select field1,field2 from
(
select field1,field2,
Rank() over
(
partition BY field1
order by field1,field2
) n
from mydb.mytable
) x
where n > 5
)
The innermost subquery just returns the raw data. Since I can't use WHERE there, I wrapped it with a subquery, the purpose of which is to 1) use WHERE to get records greater than 5 in rank and 2) select only field1 and field2. The reason why I select only those two fields is so that I can use the IN statement for deleting those records in the outermost query.
It works, but it appears a bit cumbersome. I'd like to consolidate the inner two subqueries into a single subquery. Is this possible?
Sounds like you need to use the QUALIFY clause which is the HAVING clause for Window Aggregate functions. Below is my take on what you are trying to accomplish.
Please do not run this SQL directly against your production data without first testing it.
/* Physical Delete */
DELETE TGT
FROM MyDB.MyTable TGT
INNER JOIN
(SELECT Field1
, Field2
FROM MyDB.MyTable
QUALIFY ROW_NUMBER() (PARTITION BY Field1, ORDER BY Field1,2)
> 5
) SRC
ON TGT.Field1 = SRC.Field1
AND TGT.Field2 = SRC.Fileld2
/* Logical Delete */
UPDATE TGT
FROM MyDB.MyTable TGT
,
(SELECT Field1
, Field2
FROM MyDB.MyTable
QUALIFY ROW_NUMBER() (PARTITION BY Field1, ORDER BY Field1,2)
> 5
) SRC
SET Deleted = 'Y'
/* RecordExpireDate = Date - 1 */
WHERE TGT.Field1 = SRC.Field1
AND TGT.Field2 = SRC.Fileld2

Resources