SQL Update all rows for one column with a list of values - sql

How can I set all rows of a column by manually typing the values?
My table has 3 rows, I want the column named mycolumn to have 3 values a, b and c (currently those values are NULL):
update mytable set mycolumn = ('a','b','c')
ORA-00907 missing right parenthesis
EDIT: my table is very simple, I have one column ID INT NOT NULL with values 1, 2, 3 and another column mycolumn with all NULL values and I want those values to become 'a' where ID = 1, 'b' where ID=2 etc.
EDIT2: I might have a huge amount of rows, so I want to avoid typing every single ID value where to replace mycolumn. Isn't it possible to match the ID values of 1 to 3 to the values 'a', 'b', 'c' in an automatic way, something like match(ID, ('a','b','c')) perhaps
I just want to replace all values of mycolumn by increasing order of ID. ID being strictly equivalent to what I call a row number in a matrix
EDIT3: I'd like a solution which would work in a general case with all sorts of values, not only the letters of the alphabet given here for simplicity. What if for example my values to replace in mycolumn are ('oefaihfoiashfe', 'fiaohoawdihoiwahopah', 'aefohdfaohdao')? However the ID row numbers will always be a sequence from 1 to N by 1.

Obviously, you should do this in a single update. Like this:
update mytable
set mycolumn = case id when 1 then 'a' when 2 then 'b' when 3 then 'c' end
;
More compact (but also more cryptic, and only works in Oracle, while case expressions are in the SQL standard):
update mytable
set mycolumn = decode(id, 1, 'a', 2, 'b', 3, 'c')
;
Note - this only works if there really are only three rows. If you have many more rows, make sure to add where id in (1, 2, 3) at the end. Otherwise all the OTHER values (in the other rows) will be updated to null!

You can try an update like the one below. This will update 1 > a, 2 > b, 3 > c, 4 > d, etc. When you reach ID 27, since there are no more letters, it will begin at a again and continue down the alphabet.
UPDATE mytable
SET mycolumn = CASE MOD (id, 26)
WHEN 0 THEN 'z'
ELSE CHR (MOD (id, 26) + 96)
END;
Update
To update based on any list of values, you can try an update statement like the one below. If you add a 4th item to the comma delimited list, ID 4 in mytable will be set to whatever you specified as the 4th value.
UPDATE mytable
SET mycolumn =
(SELECT COLUMN_VALUE
FROM (SELECT ROWNUM AS row_num, t.COLUMN_VALUE
FROM TABLE (
sys.odcivarchar2list ('oefaihfoiashfe',
'fiaohoawdihoiwahopah',
'aefohdfaohdao')) t)
WHERE row_num = id);

Hmmm . . . A row can only have one value. Perhaps something like this to assign random values:
update mytable
set mycolumn = (case floor(dbms_random.random * 3)
case 0 then 'a' case 1 then 'b' else 'c'
end)

if you want the 3 rows to have different values a, b and c then you will have to write 3 update statements.
update mytable set mycolumn = 'a' where id = 1;
update mytable set mycolumn = 'b' where id = 2;
update mytable set mycolumn = 'c' where id = 3;

Related

Moving a cell value to another row based on ID numbers

I am looking to move B to the above row. It can either be placed where the Null value is in Column B or another column can be created. The value of B is linked to value A through an ID. The ID for value B is always X + 2 (the values in the ID column are integers).
I can’t just move the value up because the table I am working with has thousands of rows. It must be linked to the ID’s.
Please let me know if you have any questions. Any assistance is much appreciated. Thank you.
ID
Column A
Column B
X
A
NULL
X+2
NULL
B
Keep in mind I am very new to SQL. Below is what I tried. It created a new column that only contains NULL values.
Select
Column_B
From
Table_Name
Where
Table_Name.ID = Table_Name.ID +2 ) AS Col_B_Value
You can use a conditional subselect for that
UPDATE Table_Name T1
SET Column_B = (Select
Column_B
From
Table_Name
Where
Table_Name.ID = T1.ID +2 )
WHERE Column_B IS NULL
Some databases could have a problem so you can make
UPDATE Table_Name T1
SET Column_B = (Select
T2.Column_B
From
(SELECT ID,Column_B FROM Table_Name) T2
Where
T2.ID = T1.ID +2 )
WHERE Column_B IS NULL
You could just do it with 2 updates statements
UPDATE Table
SET Column B = 'B'
WHERE ID = 'X'
UPDATE Table
SET Column B = NULL
WHERE ID = 'X+2'
If you need to do it in a select statement you could do it with a case statement too
SELECT ID,
Column A,
CASE WHEN ID = X AND Column B = NULL THEN 'B'
ELSE Column B END
FROM Table

How to randomly update rows in SQL for entire table

I have a table where for a column id, I want to randomly assign it "a","b", or "c" randomly and equally. There's also a condition where name has to be "test".
UPDATE table
WHERE name="test"
SET id=
CASE WHEN rand() < 1/3 THEN "a"
CASE WHEN rand() < 2/3 THEN "b"
CASE WHEN rand() < 1 THEN "c"
I'm not sure how this would work though, because I'm not sure if rand() will run for every row?
I'm pretty new to SQL so this is a bit confusing, thanks!
This answers the original version of the question
Just use arithmetic:
UPDATE table
SET id = 1 + floor(rand * 3)
WHERE name = 'test'
If by randomly and equally you mean that you want to ensure the number of rows in the 3 groups are distributed as equally as possible, you have to use ntile() like so:
CREATE TABLE public.test
( pk serial primary key,
id varchar,
name character varying
)
insert into test (name)values(generate_series(1,150)::varchar);
--99 rows of test data:
update test set name = 'test' where pk < 100;
-- partition by random and divide into 3 equal parts:
SELECT t.*, ntile(3) over(order by random())AS n from test t where name = 'test' ;
-- use this select in an update query:
UPDATE test
SET id = case sel.n when 1 then 'a'
when 2 then 'b'
when 3 then 'c'
END
FROM
(SELECT t.*, ntile(3) over(order by random())AS n
FROM test t WHERE name = 'test'
)sel
WHERE sel.pk = test.pk;
-- test result
select count(*) from test where name = 'test' group by id;
-- 33
-- 33
-- 33

Comparing two column values in postgres

I have table having following columns and records. I need to compare the two column values(ColumnA and ColumnB), if ColumnB>ColumnA then and update the third column from 'N' TO 'Y'
CREATE TABLE Test(ColumnA int,ColumnB int,Result Varchar(2))
INSERT INTO Test values(1,3,'N')
INSERT INTO Test values(2,1,'N')
INSERT INTO Test values(1,5,'N')
INSERT INTO Test values(8,7,'N')
I need to update Result Column='Y' for first and third row because columnB>ColumnA
Result
ColumnA ColumnB Result
1 3 Y
2 1 N
1 5 Y
8 7 N
This can be done with a simple CASE expression:
update test
set result = case
when columna > columnb then 'Y'
else 'N'
end
;
Online example: https://rextester.com/ZHIUZD82060
I would recommend to use a boolean column instead of a varchar to store "yes/no" flags. Then the update becomes as simple as set result = column_a > columnb
update test
set result =
case
when columnb > columna then 'Y'
else 'N'
end;
Hope this will help.

What SQL query can answer "Do these rows exist?"

Here is the code to create the database:
CREATE TABLE foo (
id TEXT PRIMARY KEY,
value TEXT
);
INSERT INTO foo VALUES(1, 10), (2, 20), (3, 30), (5, 50);
Now I have a set of rows and I want back 0 if the row doesnt exist, 1 if the row exists but is not the same, and 2 if the row exists exactly.
So the result of the query on (1, 11), (2, 20), (4, 40) should be 1, 2, 0.
The reason I want this is to know what query to use to insert the data into the database. If it is a 0, I do a normal insert, if it is a 1 I do an update, and if it is a 2 I skip the row. I know that INSERT OR REPLACE will result in nearly the same rows, but the problem is that it doesnt trigger the correct triggers (it will always trigger an on insert trigger instead of an update trigger or no trigger if the row exists exactly).
Also, I want to do one query with all of the rows, not one query per row.
The idea is to use an aggregation query. Count the number of times that the id matches. If there are none, then return 0. Then check the value to distinguish between 1 and 2:
select (case when max(id = 1) = 0 then 0
when max(id = 1 and value = 11) = 0 then 1
else 2
end) as flag
from table t;
You need to plug the values into the query.
EDIT:
If you want to match a bunch of rows, do something like this:
select testvalue.id,
(case when max(t.id = testvalue.id) = 0 then 0
when max(t.id = testvalue.id and t.value = testvalue.value) = 0 then 1
else 2
end) as flag
from table t cross join
(select 1 as id 10 as value union all
select 2, 20 union all
select 4, 40
) as testvalues
group by testvalues.id;
You can use the EXISTS argument in Transact-SQL. MSDN Documentation.
This returns true if a row exists. You can then use an If statement within that to check if the row is the same or different, and if true, use the RETURN argument with your specified values. MSDN Documentation.
This is based off of Gordon Linoff's answer so upvote him. I just wanted to share what I actually went with:
select testvalues.id,
(case when t.id != testvalues.id then 0
when t.value != testvalues.value then 1
else 2
end) as flag
from (select 1 as id, 11 as entity union all
select 2, 20 union all
select 4, 40
) as testvalues
LEFT OUTER JOIN foo t on testvalues.id=t.id
This prevents the full memory usage of a cross join and group by clauses.

Set Values in column B based on values in Column A in SQL2005?

I'm trying to take an existing column and parse each row for certain words in a string, i.e. Sheet, Page, Card, and based on that word (only one instance of one of these words is in a row) populate a new column in the same table with a value. If it did not find any of those words, leave Column B blank.
I.E. Column A contains the word "Sheet", populate Column B with the letter "S"
So the table would be something like:
Column A Column B
Sheet S
Page P
Card C
Any help would be appreciated!
UPDATE YourTable
SET ColumnB = CASE WHEN ColumnA LIKE '%Sheet%' THEN 'S'
WHEN ColumnA LIKE '%Page%' THEN 'P'
WHEN ColumnA LIKE '%Card%' THEN 'C'
ELSE NULL /* or '' if you prefer */
END
;WITH mappings (ColumnA, ColumnB) AS
(
SELECT 'Sheet','S' UNION ALL
SELECT 'Page','P' UNION ALL
SELECT 'Card','C'
)
UPDATE y
SET y.ColumnB= m.ColumnB
FROM YourTable y
JOIN mappings m ON y.ColumnA LIKE '%' + m.ColumnA + '%'
update myTable
set columnB = substring(columnA, 1, 1)