Insert to an identity column using sequences in DB2 - db2

How do I insert to an identity column using sequences in DB2?

INSERT INTO Table1 (seq, val1, val2, ...) VALUES (NEXT VALUE FOR seq, val1, val2, ...)

Code:
INSERT INTO Table1 (seq, val1, val2, ...) VALUES (NEXTVAL FROM seq, val1, val2, ...)

Related

Error when duplicating rows and changing a value in SQL

I know there are similar questions on SO but I wasn't able to find my exact use case. I am trying to duplicate some rows in a PostgreSQL table and change one value in them. For example, I have a table with three values and I want to grab a selection of rows based on the third value and copy them, then change the third value. Here's what I have so far:
INSERT INTO my_table ( val1, val2, val3 )
VALUES
(
( SELECT val1 FROM my_table WHERE val3 = '1' LIMIT 2, ( SELECT val2 FROM my_table WHERE val3 = '1' LIMIT 2), '2' )
I am getting an error that says "more than one row returned by a subquery used as an expression". Also, I would like to be able to test the solution with just a couple rows, so ideally I would be able to limit the SELECT statements to just a couple. Is this possible?
The VALUES keyword is used when you're inserting manual values into the table. If you want to insert based on a query, you skip that.
INSERT INTO my_table (val1, val2, val3)
SELECT val1, val2, '2'
FROM my_table
WHERE val3 = '1'
LIMIT 2;

Get distinct values from the values of a certain column with some formatting

I have a table in pgadmin (old verion pgadmin3) of the following format. Please note the commas at the beginning and the end of the values
my_table
id column_name
1 , val1,
2 , val1, val2,
3 , val2, val4, val5,
id
column_name
1
, val1,
2
, val1, val2,
3
, val2, val4, val5,
I would like to get the following output
expected outcome
new_id column_name
1 val1
2 val2
3 val4
4 val5
new_id
column_name
1
val1
2
val2
3
val4
3
val5
So basically I want the output to be of distinct values.
I have been trying a different scripts with no success. (Please again note the commas at the beginning and at the end of the strings in that column. They need to be removed too in the process)
Can you please help me on this.
Thank you,
Shaun
Split the string and discard the empty strings. Then, for each value, take the lowest matching id.
SELECT DISTINCT ON (c.c)
m.id, c.c
FROM mytab AS m
CROSS JOIN LATERAL regexp_split_to_table(m.column_name, ', *') AS c(c)
WHERE c.c <> ''
ORDER BY c.c, m.id;
id | c
----+------
1 | val1
2 | val2
3 | val4
3 | val5
(4 rows)
First normalize the data by splitting my_column into rows (this is the t CTE) and then select distinct values. trim function is used twice to clean the commas and spaces from the list string.
with t as
(
select id, l.list_item
from my_table m
cross join lateral
(
select trim(s) as list_item
from unnest(string_to_array(trim(m.column_name, ', '), ',')) s
) l
)
select distinct on (list_item) id, list_item as column_name
from t
order by list_item, id;

selecting top k column values in a row in postgresql

I have below table structure
CREATE TABLE myTable (
id1 INTEGER,
key1 VARCHAR,
key2 VARCHAR,
key3 VARCHAR,
key4 VARCHAR,
key5 VARCHAR,
val1 DOUBLE PRECISION,
val2 DOUBLE PRECISION,
val3 DOUBLE PRECISION,
val4 DOUBLE PRECISION,
val5 DOUBLE PRECISION
);
I am trying to write query to select top 3 val columns and their corresponding keys amongst given 5 key-val pairs.
something like
id1, key1, val1, key2, val2, key3, val3.
where val1, val2 and val3 are top3 amongst all five values.
I was able to write it for top value and key like below
SELECT CASE WHEN val1 = GREATEST(val1, val2, val3, val4, val5) THEN key1
WHEN val2 = .... THEN val2
.....
END AS top_key
,GREATEST(val1, val2, val3, val4, val5) AS top_val
FROM myTable
WHERE id1 = ?
but struggling to do it for top k columns !
Is there any custom function to find top k elements out of given elements ?
any other direct way to do this ?
Thanks in Anticipation !
Try this. It basically makes a "temporary" table of (key, value) pairs for every row and then selects top three of the pairs for every row.
SELECT t.id,
(array_agg((a.k, a.v) ORDER BY a.v DESC))[1] AS kv1,
(array_agg((a.k, a.v) ORDER BY a.v DESC))[2] AS kv2,
(array_agg((a.k, a.v) ORDER BY a.v DESC))[3] AS kv3
FROM t
CROSS JOIN LATERAL (
SELECT * FROM (VALUES (t.k1, t.v1), (t.k2, t.v2), (t.k3, t.v3), (t.k4, t.v4), (t.k5, t.v5)) AS a(k, v)
) AS a
GROUP BY t.id
Fiddle here: http://sqlfiddle.com/#!17/6b0c5/2

Copy rows into same table, but change value of one field

I have a list of values:
(56957,85697,56325,45698,21367,56397,14758,39656)
and a 'template' row in a table.
I want to do this:
for value in valuelist:
{
insert into table1 (field1, field2, field3, field4)
select value1, value2, value3, (value)
from table1
where ID = (ID of template row)
}
I know how I would do this in code, like c# for instance, but I'm not sure how to 'loop' this while passing in a new value to the insert statement. (i know that code makes no sense, just trying to convey what I'm trying to accomplish.
There is no need to loop here, SQL is a set based language and you apply your operations to entire sets of data all at once as opposed to looping through row by row.
insert statements can come from either an explicit list of values or from the result of a regular select statement, for example:
insert into table1(col1, col2)
select col3
,col4
from table2;
There is nothing stopping you selecting your data from the same place you are inserting to, which will duplicate all your data:
insert into table1(col1, col2)
select col1
,col2
from table1;
If you want to edit one of these column values - say by incrementing the value currently held, you simply apply this logic to your select statement and make sure the resultant dataset matches your target table in number of columns and data types:
insert into table1(col1, col2)
select col1
,col2+1 as col2
from table1;
Optionally, if you only want to do this for a subset of those values, just add a standard where clause:
insert into table1(col1, col2)
select col1
,col2+1 as col2
from table1
where col1 = <your value>;
Now if this isn't enough for you to work it out by yourself, you can join your dataset to you values list to get a version of the data to be inserted for each value in that list. Because you want each row to join to each value, you can use a cross join:
declare #v table(value int);
insert into #v values(56957),(85697),(56325),(45698),(21367),(56397),(14758),(39656);
insert into table1(col1, col2, value)
select t.col1
,t.col2
,v.value
from table1 as t
cross join #v as v

How to insert default values in SQL table?

I have a table like this:
create table1 (field1 int,
field2 int default 5557,
field3 int default 1337,
field4 int default 1337)
I want to insert a row which has the default values for field2 and field4.
I've tried insert into table1 values (5,null,10,null) but it doesn't work and ISNULL(field2,default) doesn't work either.
How can I tell the database to use the default value for the column when I insert a row?
Best practice it to list your columns so you're independent of table changes (new column or column order etc)
insert into table1 (field1, field3) values (5,10)
However, if you don't want to do this, use the DEFAULT keyword
insert into table1 values (5, DEFAULT, 10, DEFAULT)
Just don't include the columns that you want to use the default value for in your insert statement. For instance:
INSERT INTO table1 (field1, field3) VALUES (5, 10);
...will take the default values for field2 and field4, and assign 5 to field1 and 10 to field3.
This works if all the columns have associated defaults and one does not want to specify the column names:
insert into your_table
default values
Try it like this
INSERT INTO table1 (field1, field3) VALUES (5,10)
Then field2 and field4 should have default values.
I had a case where I had a very simple table, and I basically just wanted an extra row with just the default values. Not sure if there is a prettier way of doing it, but here's one way:
This sets every column in the new row to its default value:
INSERT INTO your_table VALUES ()
Note: This is extra useful for MySQL where INSERT INTO your_table DEFAULT VALUES does not work.
If your columns should not contain NULL values, you need to define the columns as NOT NULL as well, otherwise the passed in NULL will be used instead of the default and not produce an error.
If you don't pass in any value to these fields (which requires you to specify the fields that you do want to use), the defaults will be used:
INSERT INTO
table1 (field1, field3)
VALUES (5,10)
You can write in this way
GO
ALTER TABLE Table_name ADD
column_name decimal(18, 2) NOT NULL CONSTRAINT Constant_name DEFAULT 0
GO
ALTER TABLE Table_name SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
To insert the default values you should omit them something like this :
Insert into Table (Field2) values(5)
All other fields will have null or their default values if it has defined.
CREATE TABLE #dum (id int identity(1,1) primary key, def int NOT NULL default(5), name varchar(25))
-- this works
INSERT #dum (def, name) VALUES (DEFAULT, 'jeff')
SELECT * FROM #dum;
DECLARE #some int
-- this *doesn't* work and I think it should
INSERT #dum (def, name)
VALUES (ISNULL(#some, DEFAULT), 'george')
SELECT * FROM #dum;
CREATE PROC SP_EMPLOYEE --By Using TYPE parameter and CASE in Stored procedure
(#TYPE INT)
AS
BEGIN
IF #TYPE=1
BEGIN
SELECT DESIGID,DESIGNAME FROM GP_DESIGNATION
END
IF #TYPE=2
BEGIN
SELECT ID,NAME,DESIGNAME,
case D.ISACTIVE when 'Y' then 'ISACTIVE' when 'N' then 'INACTIVE' else 'not' end as ACTIVE
FROM GP_EMPLOYEEDETAILS ED
JOIN GP_DESIGNATION D ON ED.DESIGNATION=D.DESIGID
END
END