updating postgres table with unique Integer array - sql

I am not so good in queries. I have a table with column users which is of type 'users integer ARRAY'.
For e.g. it looks like users[1,2]
Now I want to update this array with new value, but it has to be distinct. For e.g. if I want to add 3 to it then the output should be users[1,2,3] and if I add 1 to it then it should not make any update.
My current query to update this column is:
UPDATE userTable SET users = array_append(users, 3) WHERE user_id=1
I am not getting how and where to define so it only takes the distinct users.
Thanks in advance.

Just don't do the update if the value is present:
UPDATE userTable
SET users = array_append(users, 3)
WHERE user_id = 1 AND NOT users #> array[3];

Related

Update value using row index

Say I have a table like below with values I want to update in specific rows, but no primary key, I only know the index of the row I want to update. Is this possible with generic SQL or would I need some DB specific tools? I'm using Postgres and SQLite. I realise this is bad DB design and the obvious solution is to simply add an id primary key to the table, but my use case is the DB is the backend for a flexible Excel-like application, where I have no control over the table schema, as it is user defined.
CREATE TABLE fruits (name TEXT);
INSERT INTO fruits VALUES (banana) (aple) (orange);
To fix the typo, I want to do something like:
UPDATE fruits SET name = 'apple' WHERE *row index* = 1;
Note I'm using 0-indexing in this pseudo code example.
Did you try
UPDATE fruits SET name='<new_name>' WHERE rowid=3 ?
rowid docs
You could try
UPDATE fruits SET name = 'apple' WHERE name =(
SELECT name FROM
(SELECT name, row_number() over (order by name) as line_number FROM fruits )
A
WHERE line_number = 1
)
So ROW_NUMBER is dynamically creating a unique number for each name, but it is doing so by sorting the results by name. So the index will be 1 if you want to select the 'Aple' entry.

SQL - Update all rows with certain condition

Hi i want to do is a query which do the following thing:
If i execute the query ,all rows will set to 0 except certain id in the where(which supposed to be always 1 and only one row can be active at the moment)
tbl_menu
id | serial
starter | varchar
plate | varchar
beverage | varchar
status | smallint
So if i have one registry with status in 1 and everything else in 0, when i execute this query, certain id i choose will change to 1 and the others to 0
also only one row status = 1
Try this:
UPDATE tbl_menu
set status = CASE WHEN id = 4 or status = 1 THEN 1 ELSE 0 END;
I think you have two choices with the design as it is.
1) Do it with two easy queries.
2) Write one more complicated query with a case statement.
I personally like easy:
UPDATE tblmenu SET status = 0 WHERE status = 1;
UPDATE tblmenu SET status = 1 WHERE id = n;
Although, having said that, I think a better approach is this...
Get rid of your status column
Create a new table called, say tblstatus with one column id
One record with the id of the record
Foreign key to your main table
Now all you have to do is:
UPDATE tblstatus SET id = n;
Faster, easier, more robust...
This is a basic update statement. But if you could give more info on the column names and on what condition you want to do the updates it would be helpful.
UPDATE tbl_menu SET (column) = value
WHERE (condition)
This doesn't solve the problem of the update, but it does solve the problem of enforcing that (at most) one row is active. Use a partial unique index:
create unique index unq_menu_active on tblmenu(flag) where flag = 1;

How to update column based on filter of another column?

I'm trying to basically update a subset of rows in a table using a filter but currently my query is updating all values instead of the intended subset. I'm not really sure what I'm missing.
Here's what the current (non working) update looks like.
UPDATE account_type
SET type_id = 3
FROM my_filter;
I have been able to successfully select the data I want, I just can't figure out how to get the update to work. I am able to access the fields correctly with the following select statement.
SELECT account_type FROM my_filter;
But when I attempt to update, it updates every field. Here's what the (working) join I have looks like, wrapped in a CTE.
WITH my_filter AS
(
SELECT account_type.type_id, username
FROM account_type
INNER JOIN user ON user.account_id = account_type.account_id
WHERE username LIKE 'filter%'
)
You need a join condition. I would guess:
UPDATE account_type
SET type_id = 3
FROM my_filter
WHERE account_type.type_id = my_filter.type_id;
Alternative, you can write this as:
UPDATE account_type
SET type_id = 3
FROM user
WHERE user.account_id = account_type.account_id AND
user.username LIKE 'filter%';

set value column where id is in the other table

I am trying to modify a table of my taking the id of another table being that this other table is with another column, taking only if the data of that column is 2, take the ID of that column and use in the one that I want to change, example:
UPDATE QuestData SET RepeatFinish = 100000
WHERE QuestID =
(
SELECT * FROM Quest WHERE QuestID = 2
);
But QuestData have so much data and table Quest too, how can i make this?
UPDATE QuestData SET RepeatFinish = 100000
WHERE QuestID in
(
SELECT id FROM Quest WHERE QuestID = 2
);
Change the id in select by yours. when using the in with an other request the select must return a one field that will be used in IN, you are using * so we don't know with what we should compare the QuestID

SQL count query, using where clause from 2 different tables

I am new to SQL. I need to run a one-time query at a few different sites to get a count. The query needs to give me a count of all records based on a where clause. But I'm having trouble figuring out the syntax.
Here's what I tried:
SELECT COUNT(KEYS.IDXKEYID) FROM KEYS, KEYFLAGS
WHERE IDXLEVELID = 1
AND KEYFLAGS.BKEYSEVERMADE = -1
Which gave me a crazy number.
Basically, IDXKEYID is a primary key, and exists in both the KEYS and KEYFLAGS table. I want a count of all IDXKEYID records in the database that meet the above WHERE clause critera. I just want 1 simple result in 1 column/row.
COUNT
-----
12346
Thanks in advance!
SELECT COUNT(DISTINCT KEYS.IDXKEYID) -- count each key only once
FROM KEYS, KEYFLAGS
WHERE KEYS.IDXLEVELID = 1
AND KEYFLAGS.BKEYSEVERMADE = -1
AND KEYS.IDXKEYID = KEYFLAGS.IDXKEYID -- you're missing this link
Or you can write it using EXISTS
SELECT COUNT(1) -- count each key only once
FROM KEYS
WHERE KEYS.IDXLEVELID = 1
AND EXISTS (
SELECT *
FROM KEYFLAGS
WHERE KEYS.IDXKEYID = KEYFLAGS.IDXKEYID -- correlate
AND KEYFLAGS.BKEYSEVERMADE = -1)