update column with numbers in sqlite table - sql

This should be very simple but I cannot figure out how to do it. I would like to modify the values of two different columns. One from 1 to the total number of rows and the other one from the total of rows to one (basically increasing and decreasing number). I tried:
start = 0
end = number_of_rows + 1
c.execute('SELECT * FROM tablename')
newresult=c.fetchall()
for row in newresult:
start += 1
end -= 1
t = (start,)
u = (end,)
c.execute("UPDATE tablename SET Z_PK = ?", t) ---> this will transform all rows with Z_PK since there is no where statement to limit
c.execute("UPDATE tablename SET Z_OPT = ?", u)
The thing is that I don't know how I can add the "where" statement since I have no values I am sure for rows (like IDs number). A possibility would be to return the current row as the argument for "where" but I don't know how to do it...

Without an INTEGER PRIMARY KEY column, your table has an internal rowid column, which already contains the values you want:
UPDATE MyTable
SET Z_PK = rowid,
Z_OPT = (SELECT COUNT(*) FROM MyTable) + 1 - rowid

Related

Complex INSERT INTO SELECT statement in SQL

I have two tables in SQL. I need to add rows from one table to another. The table to which I add rows looks like:
timestamp, deviceID, value
2020-10-04, 1, 0
2020-10-04, 2, 0
2020-10-07, 1, 1
2020-10-08, 2, 1
But I have to add a row to this table if a state for a particular deviceID was changed in comparison to the last timestamp.
For example this record "2020-10-09, 2, 1" won't be added because the value wasn't changed for deviceID = 2 and last timestamp = "2020-10-08". In the same time record "2020-10-09, 1, 0" will be added, because the value for deviceID = 1 was changed to 0.
I have a problem with writing a query for this logic. I have written something like this:
insert into output
select *
from values
where value != (
select value
from output
where timestamp = (select max(timestamp) from output) and output.deviceID = values.deviceID)
Of course it doesn't work because of the last part of the query "and output.deviceID = values.deviceID".
Actually the problem is that I don't know how to take the value from "output" table where deviceID is the same as in the row that I try to insert.
I would use order by and something to limit to one row:
insert into output
select *
from values
where value <> (select o2.value
from output o2
where o2.deviceId = v.deviceId
order by o2.timestamp desc
fetch first 1 row only
);
The above is standard SQL. Specific databases may have other ways to express this, such as limit or top (1).

How to update rows in BigQuery based on value in repeated field

I need to update the values in a repeated field for certain rows in a BigQuery table. The rows to be updated are selected based on values in the repeated field. I can't figure out how to do accomplish this. For example, let's say I have a schema like this:
move_id: integer
color: string
moved_quants: repeated
moved_quants.quantity = integer
moved_quants.value = float
And the following data:
My goal is to update the value of moved_quants.value to 0.6 * the quantity for any row that contains at least one moved_quants.value = 0. Previously, I had to perform this same task based on the color, and that was relatively simple:
UPDATE
`testing`
SET
moved_quants = ARRAY(
SELECT AS STRUCT * REPLACE(0.6 * quantity AS value)
FROM
UNNEST(moved_quants)
)
WHERE color = 'red'
However, now I need to update the rows that have at least one moved_quants.value = 0 and I can't figure out how to do this. Can anyone help?
I think I may have figured it out:
UPDATE
`testing`
SET
moved_quants = ARRAY(
SELECT AS STRUCT * REPLACE(0.6 * quantity AS value)
FROM
UNNEST(moved_quants)
)
WHERE
ARRAY_LENGTH(ARRAY(
(SELECT AS STRUCT * FROM UNNEST(moved_quants) WHERE inventory_value = 0)
)) > 0
Is that right?

How to replace a value in one field by a value from another field (different column) within the same view table (SQL)?

I'd like to know if it is possible to replace a value from one field by using a value from another column and a different row.
For Example, click this to view the table image.
I'd like the SumRedeemed value 400 in row 15 to be replaced by the value -1*(-395); the value -395 comes from the EarnPointsLeft in row 6 (both have the same CID meaning that they are the same person). Any suggestions?
You need this update statement:
update t
set t.sumredeemed = (-1) * (select earnpointsleft from FifoPtsView where cid = t.cid)
from FifoPtsView t
where t.cid = 5000100008 and t.earnpointsleft = 0
This will work if the select statement will return only 1 row.
you can simply update your table
update t
set t.sumredeemed = ABS(t2.earnpointsleft )
from FifoPtsView t join FifoPtsView t2 on t.cid = t.cid and isnull(t2.earnpointsleft,0)>0
if you want negative values you can remove ABS ,
please give me your feedbacks

Improving App Speed with a Second Serial column in PostgreSQL

Edit: (Explanation added)
I have a table that stores some data, it has the structure indicated below.
id tparti_id orde desc
1 1 10 One thing
2 1 20 Another thing
3 1 30 Last task of the month
4 2 10 First of second month
5 2 20 Second and last of second month
6 3 10 First of third month
The orde field it's the the sequence of rows with the same tparti_id, this value it's used on our app to sort the contents given tparti_id, the user can reorder it changing the values in order.
The values stored came from a text file and are parsed by a CakePHP app.
When a new row it's inserted the next value in the sequence of orde is calculated by searching the current value in orde and adding 10 given an id, if no orde is found returns 10
public function nextOrden($tpid){
$sql = "select orde from tdpies where tparti_id =".$tpid." order by orde desc limit 1;";
$r = $this->query($sql,$cachequeries = false);
if ($r){
$res = $r[0][0]['orde'] + 10;
} else {
$res = 10;
}
return $res;
}
It's working ok when inserting few records, but when inserting thousands of records it's time consuming.
How can improve performance:
Using a trigger when a new record it's created?
Using a new sequence with some trickery inside?
Thanks
You seem to have an auto-incremented id so you could calculated orde when you query table rather tha when you create it:
select p.*, 10 * (row_number() over (partition by tparti_id order by id)) as orde
from tdpies p;
If you want to handle this on insert, then add an index on tdpies(tparti_id, orde). Inside the trigger, you'll have something like:
new.orde := (select coalesce(max(orde), 0) + 10
from tdpies p
where p.tparti_id = new.tparti_id
);
It can (and should) be done in SQL in instead of in PHP
$sql = "
select coalesce(max(orde), 0) + 10 as new_id
from tdpies
where tparti_id = $tpid
"
If max(orde) returns null when there is no matching tparti_id the coalesce function returns 0.
Notice that it is not necessary to concatenate $tpid as it will be evaluated inside a double quoted string.
It is better to do the insert in the same query
insert into tdpies (
id, tparti_id, orde, description
)
select
1, $tpid,
coalesce(max(orde), 0) + 10,
'something about months'
from tdpies
where tparti_id = $tpid
You need an unique constraint (tparti_id, orde) in order to keep the table integrity.

looping through a data table vb

I'm trying to loop through a data table that has multiple values for my constraint. How can I keep the first value and add together all the other values that match my constraint.
For i = 0 To ds.Tables(0).Rows.Count - 1
If ds.Tables(0).Rows(i).Item("TEND_POS_ID") = 8 Then
'This only returns the last value
'Value 1 = 2
'Value 2 = 7.5
'should = 9.5 but it is showing 7.5
tmpCoupon = ds.Tables(0).Rows(i).Item("TENDER_AMT")
End If
Next
txtCoupon.Text = tmpCoupon
If I understand your question correctly, you need to add the values of TENDER_AMT where the value in TEND_POS_ID is 8. If this is the case you could use the Select method of the DataTable
Dim rows = ds.Tables(0).Select("TEND_POS_ID = 8")
for each r in rows
tmpCoupon += Convert.ToDecimal(r("TENDER_AMD"))
Next
However, rembember that this kind of work (SUM a column grouping by another column) is usually better resolved by the query that you submit to the database. Something like this:
SELECT TEND_POS_ID, SUM(TENDER_AMD) FROM Table1 GROUP BY TEND_POS_ID