After adding a new column is it possible to insert values for that column using only one query?
TABLE:
id | category | level | new_column_name
---+-------------+-------+----------------
1 | Character | 3 |
2 | Character | 2 |
3 | Character | 2 |
4 | Character | 5 |
I'd need to do something like
INSERT INTO table_name
(new_column_name)
VALUES
('foo'), -- value for new_column_name : row1
('bar'), -- value for new_column_name : row2
...
;
I already used a similar query using postgresql cli in order to insert values, but it fails becauase uses null for the unset column values, one of which (id) is PRIMARY_KEY, so it can't be NULL.
This is the error it logs:
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null, null, null, 1359).
EDIT:
What I'm doing is more an update than an insert, but what I would be able to do is to insert all the different values at once.
For instance, if possible, I would avoid doing this:
UPDATE table_name
SET new_column_name = 'foo'
WHERE id = 1;
UPDATE table_name
SET new_column_name = 'bar',
WHERE id = 2;
--...
You can use VALUES so as to construct an in-line table containing the values to be updated.:
UPDATE table_name AS v
SET new_column_name = s.val
FROM (VALUES (1, 'foo'), (2, 'bar')) AS s(id, val)
WHERE v.id = s.id
Demo here
You can use a huge CASE:
UPDATE table_name
SET new_column_name
= CASE WHEN id = 1 THEN 'foo'
WHEN id = 2 THEN 'bar'
END;
Related
Again, I can't seem to find a simple way to do this.
But I've been coding for a while now and potentially I'm just tired and losing it!
SELECT
case when "colA" = '1' OR "colB" = 1 then 1
else 0
end as "colc"
FROM t1
How do I add this new column to t1, preserving the order etc.?
I know I can run
ALTER t1 ADD COLUMN colc
but how do I populate the values correctly?
Despite the documentation you can find around, it is actually possible to create computed columns. Here is an example:
create or replace table computedColTest (id bigint, id2 bigint, derived bigint as (id * id2));
insert into computedColTest values (3, 5);
select * from computedColTest;
The result is:
However, I don't think it is possible to directly translate the logic you need as you can't seem to be able to use a logical operator within it. You can however adapt it a bit to your situation and translate your switch into a mathematical operation that is compatible.
I think 'Virtual Columns' is how derived columns are known in Snowflake.
Check this out:
CREATE
OR REPLACE TABLE Virtual_Column_Example (
colA INT
, colB INT
, derived INT AS ( IFF(colA = 1 or colB = 1, 1, 0) )
);
INSERT INTO Virtual_Column_Example
VALUES (0, 0), (1, 1), (1, 2), (2, 1),(2, 2);
SELECT * FROM Virtual_Column_Example;
/*
---------------------
colA | colB | derived
---------------------
0 | 0 | 0
1 | 1 | 1
1 | 2 | 1
2 | 1 | 1
2 | 2 | 0
---------------------
*/
I actually found a way that works well, just use UPDATE
ALTER TABLE t1 ADD COLUMN "col3" INTEGER DEFAULT 0;
UPDATE t1
SET "col3"= 1
WHERE "col1" = 1 OR "col2" = 1;
I have to add a new column Isactive with (data type bit, not null)
ANd Populate the column with:
1 = active
0 = not active (default value).
Thanks in Advance.
I tried this by searching old question :
"
alter table tblname
add (STATUS VARCHAR(15) default '0',
constraint conSTATUS check (STATUS in ('1', '0')))
"
but how to set 1 = active & 0 = not active.
Add a computed column. This is not a constraint thing:
alter table NCT_UserRegistration
add isactive as (case when status = 'Active' then 1 else 0 end);
bit is not really a SQL data type (although some databases do support it. An int should be fine for your purposes.
but how to set 1 = active & 0 = not active
You don't set anything.
STATUS is a flag column and it can be translated in the presentation layer as you wish.
When you query the table use a CASE expression like this:
select
case STATUS
when 0 then 'not active'
when 1 then 'active'
end
from tblname
I believe you wanted to know how will you add values true and false to the table. I will start from a demo sample of your table(just for example):
create table tblname(id int, name varchar(20))
I will insert one row:
insert into tblname values (1, 'Marc')
This select query select * from tblname will result:
| ID | name |
| 1 | Marc |
Then we alter the table and add a BIT column called Isactive (with the constraint from your question)
alter table tblname add
Isactive bit default 0 not null,
constraint conSTATUS check (Isactive in ('1', '0'));
Because the default value is 0 then the row with ID = 1 and name = 'Marc' will have a new value of the column Isactive set to 0. But when you run this query select * from tblname again it will give you this results:
| ID | name | isactive |
| 1 | Marc | False |
If you then insert another row in your table like this:
insert into tblname values (2, 'Ann', 1);
with this query select * from tblname your results will be:
| ID | name | isactive |
| 1 | Marc | False |
| 1 | Ann | True |
I hope this helps.
Here is a DEMO
P.S. More interesting thins about BIT type in SQLServer you can find here:
https://www.sqlservertutorial.net/sql-server-basics/sql-server-bit/
I have a table containing values:
dbid name userid
------------------------------
154 xyz NULL
987 xyz NULL
777 xyz 5
111 abc NULL
745 abc NULL
748 abc 6
expected output:
dbid name userid
------------------------------
154 xyz 5
987 xyz 5
777 xyz 5
111 abc 6
745 abc 6
748 abc 6
There are all null values in the userid column except one for one name. I want to set 5 in userid for all rows where name = 'xyz'.
Similarly, want to update the table to set 6 in userid where name = 'abc'.
What should be the query to update a table for the above scenario?
Note: Above is just an example. I have a table containing hundreds of thousands of records. I cannot write id 5 or 6 in the query.
try this
update table_name
set table_name.userid = (
select top(1) ss.userid
from table_name ss
where ss.name = table_name.name
and ss.userid is not null
)
where table_name.userid is null
This query is searching first record userid where name is the same and updating if userid is null
You could update your table with a single UPDATE statement given the fact that the name idicates the userid. You can use the following query but if only such a unique dependence of those to attribute is present.
UPDATE table_name
SET name = (SELECT TOP 1 temp.userid FROM table_name temp WHERE temp.name = name)
WHERE userid is null;
Should I assume that columns dbid and name not null in the table defention? then also is the question the "output" do you want it as a result to a query, view or SP? Anyway simply put I would personly divid the table in to two tables.
table 1:
dbid name
---------------
154 xyz
987 xyz
777 xyz
111 abc
745 abc
748 abc
table 2:
name userid
------------------
xyz 5
abc 6
Then when i wanted the userid id for a specfic dbid I would simply:
SELECT A.dbid, A.name, B.userid FROM DATABASE.TABLE1 A INNER JOIN DATABASSE.TABLE2 B ON A.name = B.name
Which would result in output table:
dbid name userid
------------------------------
154 xyz 5
987 xyz 5
777 xyz 5
111 abc 6
745 abc 6
748 abc 6
Try this:
DECLARE #DataSource TABLE
(
[dbid] INT
,[name] SYSNAME
,[userid] SMALLINT
);
INSERT INTO #DataSource ([dbid], [name], [userid])
VALUES (154, 'xyz', NULL)
,(987, 'xyz', NULL)
,(777, 'xyz', 5)
,(111, 'abc', NULL)
,(745, 'abc', NULL)
,(748, 'abc', 6);
WITH DataSource AS
(
SELECT [dbid]
,[name]
,[userid]
,MIN([userID]) OVER (PARTITION BY [name]) AS [userid_precalc]
FROM #DataSource
)
UPDATE DataSource
SET [userid] = [userid_precalc]
WHERE [userid] IS NULL;
SELECT *
FROM #DataSource;
Please try the below query
update table_name
set userid=(select top 1 T.userid from table_name T where T.name=table_name.name and T.userid is not null )
where userid is null
Try this:
1) Select your data into a dummy table.
SELECT * INTO dummy_tbl FROM myTable WHERE userid is not null
Query shall insert all data with UserID not null.
2) Execute your update command
update myTable set userid = (select userID from dummy_tbl where dummy_tbl.name = myTable.name)
3) Remove your dummy table created.
drop table dummy_tbl
You are good to go, all userIDs has been updated accordingly.
BR, Moiyd
use two update query
update table_name
set userid=5
where name = 'xyz';
update table_name
set userid=6
where name = 'abc';
Since you have lakh of record to update Table variable and window function should be avoided.
My idea is similar to #Moiyd.
First create non clustered indexon original table name column.if Useris not already Clustered index then,
Create Non Clustered index ix_myTable_name on myTable(name) include(userid)
if userid is CI then no need of
include(userid)
Store not null name and userid in separate table.
Create table dummy_tbl (name varchar(100),userid int)
Create Non Clustered index ix_dummy_name on dummy_tbl(name) include(userid)
insert into dummy_tbl (userid,name)
SELECT userid FROM myTable WHERE userid is not null
update T
set userid = T.userid
from myTable T
inner join dummy_tbl d on d.name = T.name
Drop table dummy_tbl .
If possible permanently store value of dummy_tbl because that is the best and normalise way.you can store all non repeating column in dummy_tbl
Suppose I have a simple table:
CREATE TABLE user(
id INT NOT NULL PRIMARY KEY,
name VARCHAR(32) NOT NULL,
)
Is there a way to alter this table so id will become AUTO_INCREMENT field?
I tried the following with no luck:
ALTER TABLE (no such syntax)
Creating another table with auto increment ID, and copying the data from the original one (didn't work because of the error: Cannot insert into or update IDENTITY/AUTO_INCREMENT column "id")
Thanks!
I would try to just rank the rows, and use the sequence for future inserts.
\set AUTOCOMMIT 'on'
CREATE TABLE t1 (
val char(1)
);
INSERT INTO t1 VALUES ('a');
INSERT INTO t1 VALUES ('b');
INSERT INTO t1 VALUES ('c');
INSERT INTO t1 VALUES ('d');
CREATE TABLE t2 (
id int,
val char(1)
);
INSERT INTO t2 (val, id)
SELECT val, RANK() OVER (ORDER BY val) as id
FROM t1;
SELECT * FROM t2;
We get:
id | val
----+-----
1 | a
3 | c
2 | b
4 | d
Success!
Let's prepare the table for future inserts:
-- get the value to start sequence at
SELECT MAX(id) FROM t2;
-- create the sequence
CREATE SEQUENCE seq1 START 5;
-- syntax as of 6.1
-- modify the column to add next value for future rows
ALTER TABLE t2 ALTER COLUMN id SET DEFAULT NEXTVAL('seq1');
Quick test:
INSERT INTO t2 (val) VALUES ('e');
INSERT INTO t2 (val) VALUES ('f');
SELECT * FROM t2;
We get:
id | val
----+-----
4 | d
2 | b
3 | c
6 | f
1 | a
5 | e
Hope this helps.
The following is required due to records being entered by 3rd parties in a web application.
Certain columns (such as Category) require validation including the one below. I have a table OtherTable with the allowed values.
I need to identify how many occurrences (ie: IF) there are of the current table's column's value in a different table's specified column. If there are no occurrences this results in a flagged error '1', if there are occurrences, then it results in no flagged error '0'.
If `Category` can be found in `OtherTable.ColumnA` then return 0 else 1
How can I do this please?
If Category can be found in OtherTable.ColumnA then return 0 else 1
You could use CASE with EXISTS
SELECT CASE WHEN EXISTS(
SELECT NULL
FROM AllowedValues av
WHERE av.ColumnA = Category
) THEN 0 ELSE 1 END AS ErrorCode
, Category
FROM [Table]
Edit: Here's a sql-fiddle: http://sqlfiddle.com/#!3/55a2e/1
Edit: I've only just noticed that you want to use a computed column. As i've read you can only use it with scalar values and not with sub-queries. But you can create a scalar valued function.
For example:
create table AllowedValues(ColumnA varchar(1));
insert into AllowedValues Values('A');
insert into AllowedValues Values('B');
insert into AllowedValues Values('C');
create table [Table](Category varchar(1));
insert into [Table] Values('A');
insert into [Table] Values('B');
insert into [Table] Values('C');
insert into [Table] Values('D');
insert into [Table] Values('E');
-- create a scalar valued function to return your error-code
CREATE FUNCTION udf_Category_ErrorCode
(
#category VARCHAR(1)
)
RETURNS INT
AS BEGIN
DECLARE #retValue INT
SELECT #retValue =
CASE WHEN EXISTS(
SELECT NULL
FROM AllowedValues av
WHERE av.ColumnA = #category
) THEN 0 ELSE 1 END
RETURN #retValue
END
GO
Now you can add the column as computed column which uses the function to calculate the value:
ALTER TABLE [Table] ADD ErrorCode AS ( dbo.udf_Category_ErrorCode(Category) )
GO
Here's the running SQL: http://sqlfiddle.com/#!3/fc49e/2
Note: as #Damien_The_Unbelieve has commented at the other answer, even if you persist the result with a UDF, the value won't be updated if the rows in OtherTable change. Just keep that in mind, so you need to update the table manually if desired with the help of the UDF.
select mt.*,IFNULL(cat_count.ct,0) as Occurrences from MainTable mt
left outer join (select ColumnA,count(*) as ct from OtherTable) cat_count
on mt.Category=cat_count.ColumnA
Result:
mt.col1 | mt.col2 | Category | Occurrences
### | ### | XXX | 3
### | ### | YYY | 0
### | ### | ZZZ | 1