inserte data with incremented values - sql

I have this table tab1
name
-----
'big'
'smal'
'bird'
tab2
id name
-- ---
1 empty
2 empty
3 empty
4 empty
I want to insert the name from tab1 to tab2 with incremented id
this is desired result
id name
-- ---
1 empty
2 empty
3 empty
4 empty
5 'big'
6 'smal'
7 'bird'

The correct way to handle this is for table2 to define id as an identity column. You do this when you define the table:
create table table2 (
id int identity primary key,
. . .
Then you can simply do:
insert into table2(name)
select name
from table1;
You should consider defining the table correctly, if it is not. But, you can also do this in more recent versions of Sybase doing:
insert into table2(name)
select maxid + row_number() over (order by name), name
from table1 cross join
(select max(id) as maxid from table2) x;
Note: This will assign the id values in alphabetical order.

Related

Increment based on max value BigQuery

I have two tables.
TABLE A:
OBJECTID ID
NULL 41230
NULL 00004
NULL 00005
TABLE B:
OBJECTID ID
241231 00001
241230 00002
I'm trying to write a query that increments values for the OBJECTID field in Table A based on the max value in Table B. For example the OBJECTID field for the first row in Table A would then be 241232.
Using ROW_NUMBER() over (Order by OBJECTID ASC) works if I wanted to start with the value 1 and increment. But I need it to join on Table B and start on Table B's max value and then increment.
I've tried this but get a query error Query error: Table-valued function not found tableB:
UPDATE `tableA`
SET OBJECTID = (SELECT MAX(OBJECTID) as seq
FROM `tableB`
((SELECT ROW_NUMBER() over (Order by seq ASC))
)) WHERE OBJECTID IS NULL;
In BigQuery is easier create a new table that overwrite the actual. You can do it with this select:
with max_id as (
select max(objectid) as objectid from tableB
),
table_a_new_id as (
select
* except (objectid),
(select objectid from max_id) + dense_rank() over (order by id) as objectid
from tableA
where objectid is null
)
select * from table_a_new_id
union all
select * from tableA where objectid is not null
If you can't replace the table directly, you can save the result in a temporary table and then run the update:
update tableA
set tableA.objectid = new_table_a.objectid
from temp_new_tableA
where tableA.objectid is null and tableA.id = temp_new_tableA.id

INSERT into table if doesn't exists and return id in both cases

I am trying to write a complex query in POSTGRES, this question is subquery of that.
Here is my table (id is primary key and auto increment):
id appid name
1 2 abc
2 2 cde
In this table, I want to get id where name is "xyz" and appid=2 and if that doesn't exists, insert and return the ID.
I know there are several similar questions which somewhat same asks, which I already tried but doesn't seems working.
This is what I have tried to exsecute which didn't work as expected:
INSERT INTO table_name (appid, name) SELECT 2, 'xyz' WHERE NOT EXISTS (SELECT id from table_name WHERE appid=2 AND name='xyz') returning id
This works well when a new element is added and returns the ID of newly added element but doesn't return anything when a row already exists.
For ex
INSERT INTO table_name (appid, name) SELECT 2, 'abc' WHERE NOT EXISTS (SELECT id from table_name WHERE appid=2 AND name='abc') returning id
This doesn't return anything.
You can do:
with id as (
select id
from table_name
where appid = 2 and name = 'xyz'
),
i as (
insert table_name (appid, name)
select 2, 'xyz'
where not exists (select 1 from id)
returning id
)
select id
from id
union all
select id
from i;

update one table with data from another using derived key value

Table 1:
id name desc
------------------
1 a abc
2 b def
3 c adf
Table 2:
name desc
------------
x 123
y 345
How do I run an sql update query that can update Table 1 with Table 2's name and desc using the id of table 1 and rownum in table2? It's okay to assume that rownum in table2 is the same as id of table 1. So the end result I would get is
Table 1:
id name desc
------------------
1 x 123
2 y 345
3 c adf
Below are scripts for table creation and record insertion
create table table1 (
id number,
name varchar2(10),
desc_ varchar2(10)
);
create table table2 (
name varchar2(10),
desc_ varchar2(10)
);
insert into table1 values(1, 'a', 'abc');
insert into table1 values(2, 'b', 'def');
insert into table1 values(3, 'c', 'ghi');
insert into table2 values( 'x', '123');
insert into table2 values( 'y', '456');
Credits to "update one table with data from another"
There is no such thing as "rownum" in a table. SQL tables represent unordered sets, so there is no ordering without an ordering column.
Oracle does provide rowid as a built-in column identifier. This is not the same as rownum and is not guaranteed to be in order.
You can use rownum, but the value is not guarantee to have any particular meaning and might change between runs:
update table1
set (name, desc) = (select name, desc
from (select t2.*, rownum as seqnum
from table2
) t2
where seqnum = table1.id
)
where id <= (select count(*) from table2);

How to find minimum values in a column in sql

If I have a table like this:
id name value
1 abc 1
2 def 4
3 ghi 1
4 jkl 2
How can I select a new table that still has id, name, value but only the ones with a minimum value.
In this example I need this table back:
1 abc 1
3 ghi 1
Finding those values is pretty straightforward:
SELECT *
FROM YourTable
WHERE value = (SELECT MIN(Value) FROM YourTable);
As for the right syntax for putting those rows in another table, that will depend on the database engine that you are using.
An alternative to #Lamak's solution could be to use the rank window function. Depending on the exact scenario, it may perform quite better:
SELECT id, name, value
FROM (SELECT id, name, value, RANK() OVER (ORDER BY value ASC) AS rk
FROM mytable) t
WHERE rk = 1
not sure exactly if this is what you're trying to do, but I think this would work:
--creating #temp1 to recreate your table/example
CREATE TABLE #TEMP1
(id INT NOT NULL PRIMARY KEY,
name CHAR(3) NOT NULL,
value INT NOT NULL)
INSERT INTO #TEMP1
VALUES
(1,'abc',1),
(2,'def',4),
(3,'ghi',1),
(4,'jkl',2)
-verify correct
SELECT * FROM #temp1
--populate new table with min value from table 1
SELECT *
INTO #TEMP2
FROM #TEMP1
WHERE value = (SELECT MIN(value)
FROM #TEMP1)
SELECT * FROM #TEMP2

SQL Server insert with row N referencing the identity of the N - 1 row. Possible?

I have a SQL Server 2008 DB with a table like this (Table1):
ID ParentID Name
-- -------- ---
11 NULL Foo
12 11 Bar
13 12 etc
ID is declared with IDENTITY.
I have the values Foo, Bar, etc as rows in another table (Table2) and I must insert them in Table1.
The inserted values must be in a parent child relation in Table1, with ParentID column from row N pointing to ID of row N-1.
Is it possible with one statement to insert the values with the relations between them?
-- Insert all names in first table
insert Table1
(Name)
select Name
from Table2
-- For each row in Table1,
-- Search for the matching row in Table2,
-- Then look up the "parent" row in Table2,
-- And back to Table1 for the "parent" id
update t1
set ParentID = t1_parent.ID
from Table1 t1
join Table2 t2
on t1.Name = t2.name
cross apply
(
select top 1 *
from Table2 t2_parent
where t2_parent.ID < t2.ID
order by
t2_parent.ID desc
) t2_parent
join Table1 t1_parent
on t1_parent.Name = t2_parent.Name
Since you asked if you could do this in one statement, here is an answer for that. I can't help but feel that if you had given more information I would be telling that whatever you're doing this for should be solved another way. I'm having a hard time coming up with a good reason to do this. Here is a way to do it regardless though:
I am assuming Table1 has Id, ParentId, and Name, and that Table2 has Id and Name (you said you got the names Foo, Bar, whatever from Table2). I'm also assuming there is some order you can impose.
CREATE TABLE #T
(
Id INT IDENTITY(1, 1)
, ParentId INT
, Name VARCHAR(100)
)
CREATE TABLE #T2
(
Id INT IDENTITY(1, 1)
, Name VARCHAR(100)
)
INSERT #T2
(
Name
)
VALUES ('Foo'), ('Bar')
INSERT #T
(
ParentId
, Name
)
SELECT
NULLIF(IDENT_CURRENT('#T')
+ ROW_NUMBER() OVER(ORDER BY T2.Name)
- 2, (SELECT ISNULL(MIN(Id), 1) - 1 FROM #T))
, T2.Name
FROM #T2 T2
SELECT * FROM #T
DROP TABLE #T
DROP TABLE #T2