SQLite increment Integer Primary Key and Unique Constraint conflict - c++

I have a SQLite database.
When writing move rows function, which moves rows from one table to another I need to have a query for incrementing column with name "row" which is INTEGER PRIMARY KEY, but there is an error. It is critical to have indexing with row in my task. The condition in example is WHERE row >= 2 because i am inserting rows from other table into position 2.
"UPDATE '4' SET row = row + 1 WHERE row >= 2"
Error("19", "Unable to fetch row", "UNIQUE constraint failed: 4.row")
The problem's origin WHERE row >= 2" part. How to overcome this problem?

The problem's origin WHERE row >= 2" part.
I'm inclined to disagree. The problem is not with which rows are updated, it is with the order in which they are updated.
Very likely SQLite will process rows in rowid order, which almost certainly is also increasing order of the row column, since that column is an auto-incremented PK. Suppose, then, that the table contains two rows with row values 2 and 3. If it processes the first row first, then it attempts to set that row's row value to 3, but that produces a constraint violation because that column is subject to a uniqueness constraint, and there is already a row with value 3 in that column.
How to overcome this problem?
Do not modify PK values, and especially do not modify the values of surrogate PKs, which substantially all auto-increment keys are.
Alternatively, update the rows into a temporary table, clear the original table, and copy the updated values back into it. This can be extremely messy if you have any FKs referencing this PK, however, so go back to the "Do not modify PK values" advice that I led off with.

First: '4' is not a table name. The UPDATE statement expects a table name where you have written '4'. For example:
UPDATE table1 SET row = row + 1 WHERE row >= 2
Second: Just do not use row as a primary key (or unique key, for that matter) when it obviously is not meant as primary key but as a changing row number. Create a separate column that can be used as primary index of that table instead.

Related

Power BI: shifting a column one row above

I have a case that I want find the duration for each "state_id", by subtracting its change_time from the time just below it.
So I want to generate a new column that duplicates the column "change_time" and shifting all values one row up, so the change_time #2(in red) would come next to change_time #3(in red).
Is there a way to shift that column one row up?
After a lot of thinking and researching. I have solved it with the following steps:
Sort you columns of interest from A-Z (in my case sort: ticket_id, then history_type_id, then stat_id)
make a first new index column starting from 0 using "Index column from 0".
make a second new index column starting from 1 using "Index column from 1".
merge your query with itself using "merge query" based in the two new indices.
expand the merged query for the date column only.
Now you will have a new date column, duplicated from the old one with a shift of one row.
2)

Sqlite Query to remove duplicates from one column. Removal depends on the second column

Please have a look at the following data example:
In this table, I have multiple columns. There is no PRIMARY KEY, as per the image I attached, there are a few duplicates in STK_CODE. Depending on the (min) column, I want to remove duplicate rows.
According to the image, one stk_code has three different rows. Corresponding to these duplicate stk_codes, value in (min) column is different, I want to keep the row which has minimum value in (min) column.
I am very new at sqlite and I am dealing with (-lsqlite3) to join cpp with sqlite.
Is there any way possible?
Your table has rowid as primary key.
Use it to get the rowids that you don't want to delete:
DELETE FROM comparison
WHERE rowid NOT IN (
SELECT rowid
FROM comparison
GROUP BY STK_CODE
HAVING (COUNT(*) = 1 OR MIN(CASE WHEN min > 0 THEN min END))
)
This code uses rowid as a bare column and a documented feature of SQLite with which when you use MIN() or MAX() aggregate functions the query returns that row which contains the min or max value.
See a simplified demo.

How do I change the individual value to be summed during annotation in Django?

I am front end developer new to django. There is a certain column(server_reach) in our postgres DB which has values of (1,2). But I need to write a query which tells me if at least one of the filtered rows has a row with reachable values( 1= not reachable, 2 = reachable).
I was initially told that the values of the column would be (0,1) based on which I wrote this:
ServerAgent.objects.values('server').filter(
app_uuid_url=app.uuid_url,
trash=False
).annotate(serverreach=Sum('server_reach'))
The logic is simple that I fetch all the filtered rows and annotate them with the sum of the server_reaches. If this is more than zero then at least one entry is non-zero.
But the issue is that the actual DB has values (1,2). And this logic will not work anymore. I want to subtract the server_reach of each row by '1' before summing. I have tried F expressions as below
ServerAgent.objects.values('server').filter(
app_uuid_url=app.uuid_url,
trash=False
).annotate(serverreach=Sum(F('server_reach')-1))
But it throws the following error. Please help me getting this to work.
AttributeError: 'ExpressionNode' object has no attribute 'split'
Use Avg instead of Sum. If average value is greater than 1 then at least one row contains value of 2.

Update each column's value pertaining to a specific row number? sqlite sqlite3

I and terrible with databases and sql, but know the basics and this is a bit beyond basics I believe. I need a way to update a an entire rows values, where the row is selected by row number, because I have no guarantee of a value pertaining to any of the columns in that row.
Example DB Table:
Col1 Col2 Col3
a b c
d e f
g h i
So I need a way to for say
Update exampleTableName
Set Col1 = 'j', Col2 = 'k', Col3 = 'l'
Where rowNumber = 2
I am writing this in c++ and using sqlite3, but just the Query should do for me.
Thanks
Edit:
I know this sounds ridiculous and many will ask why the table is set up this way but I am not in control of that. All I can say is that I am able to figure out a row number and need to update each columns value according to what is stored in another variable. Normally these variables will hold the value I want to look up, but it isn't ever guaranteed. So I can only recall the row they want and store it at the time of the look up and then update (the last selected row) by keeping track up its index and updating its values according to w/e is in those variables, which could be the same or could have changed.
By default, every row in SQLite has a special column, usually called the "rowid", that uniquely identifies that row within the table. You can use that to select your row.
However if the phrase "WITHOUT ROWID" is added to the end of a CREATE TABLE statement, then the special "rowid" column is omitted. There are sometimes space and performance advantages to omitting the rowid.
Update exampleTableName Set Col1 = 'j', Col2 = 'k', Col3 = 'l' Where rowid= 2
your table needs some form of a primary key... at a minimum you should add a column named Key INT IDENTITY(1,1) this will give each row a number.

sql Column with multiple values (query implementation in a cpp file )

I am using this link.
I have connected my cpp file with Eclipse to my Database with 3 tables (two simple tables
Person and Item
and a third one PersonItem that connects them). In the third table I use one simple primary and then two foreign keys like that:
CREATE TABLE PersonsItems(PersonsItemsId int not null auto_increment primary key,
Person_Id int not null,
Item_id int not null,
constraint fk_Person_id foreign key (Person_Id) references Person(PersonId),
constraint fk_Item_id foreign key (Item_id) references Items(ItemId));
So, then with embedded sql in c I want a Person to have multiple items.
My code:
mysql_query(connection, \
"INSERT INTO PersonsItems(PersonsItemsId, Person_Id, Item_id) VALUES (1,1,5), (1,1,8);");
printf("%ld PersonsItems Row(s) Updated!\n", (long) mysql_affected_rows(connection));
//SELECT newly inserted record.
mysql_query(connection, \
"SELECT Order_id FROM PersonsItems");
//Resource struct with rows of returned data.
resource = mysql_use_result(connection);
// Fetch multiple results
while((result = mysql_fetch_row(resource))) {
printf("%s %s\n",result[0], result[1]);
}
My result is
-1 PersonsItems Row(s) Updated!
5
but with VALUES (1,1,5), (1,1,8);
I would like that to be
-1 PersonsItems Row(s) Updated!
5 8
Can somone tell me why is this not happening?
Kind regards.
I suspect this is because your first insert is failing with the following error:
Duplicate entry '1' for key 'PRIMARY'
Because you are trying to insert 1 twice into the PersonsItemsId which is the primary key so has to be unique (it is also auto_increment so there is no need to specify a value at all);
This is why rows affected is -1, and why in this line:
printf("%s %s\n",result[0], result[1]);
you are only seeing 5 because the first statement failed after the values (1,1,5) had already been inserted, so there is still one row of data in the table.
I think to get the behaviour you are expecting you need to use the ON DUPLICATE KEY UPDATE syntax:
INSERT INTO PersonsItems(PersonsItemsId, Person_Id, order_id)
VALUES (1,1,5), (1,1,8)
ON DUPLICATE KEY UPDATE Person_id = VALUES(person_Id), Order_ID = VALUES(Order_ID);
Example on SQL Fiddle
Or do not specify the value for personsItemsID and let auto_increment do its thing:
INSERT INTO PersonsItems( Person_Id, order_id)
VALUES (1,5), (1,8);
Example on SQL Fiddle
I think you have a typo or mistake in your two queries.
You are inserting "PersonsItemsId, Person_Id, Item_id"
INSERT INTO PersonsItems(PersonsItemsId, Person_Id, Item_id) VALUES (1,1,5), (1,1,8)
and then your select statement selects "Order_id".
SELECT Order_id FROM PersonsItems
In order to achieve 5, 8 as you request, your second query needs to be:
SELECT Item_id FROM PersonsItems
Edit to add:
Your primary key is autoincrement so you don't need to pass it to your insert statement (in fact it will error as you pass 1 twice).
You only need to insert your other columns:
INSERT INTO PersonsItems(Person_Id, Item_id) VALUES (1,5), (1,8)