Insert Max Value of Column into Another Column - sql

I have a table defined by:
create table apple(
A number,
B number);
Now, I need to get values in the table such as the following:
A B
------------------
1 4(max of A)
2 4(max of A)
3 4(max of A)
4 4(max of A)
How can I insert these rows, making B the maximum value of A?

Welp, first you want to insert 1-4 into your table:
insert into apple (a) values (1)
insert into apple (a) values (2)
insert into apple (a) values (3)
insert into apple (a) values (4)
Next, you're going to want to update your table to set b:
update apple set b = (select max(a) from apple)
As you can see, it's a two-part process. You can't get the max of a until you've created that column!

And of course, if you're wanting to have a select statement to grab that other field, use the OVER clause:
SELECT a, MAX(a) OVER() as b
FROM table;
Edited:
And for an existing table you can do:
UPDATE t SET b = maxcnt
FROM (
SELECT *, MAX(a) OVER() as maxcnt
FROM table
) t;
(I think this works in Oracle... definitely fine in MS-SQL)
Rob

Since 11g version you are able to use Virtual colums (their values calculated in real-time)
So that you should change your column definition as follows:
create table apple (
A number,
B number GENERATED ALWAYS AS ( max(A) ) VIRTUAL
);
I dont have Oracle 11g for testing, so cant check, but it should be working.
Also you could use user-defined function for Virtual column.
See http://www.oracle-base.com/articles/11g/VirtualColumns_11gR1.php for more examples and info!
Official docs for Create table in 11g:
http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_7002.htm

Related

Insert only new records that are added to TABLE A into TABLE B

Presently I have 2 tables in a SQL database: Table A and Table B
I am using the syntax
Insert Into TABLE B
Select id, col, col, col......
From TABLE A
Where id NOT IN (SELECT id from TABLE B)
End;
This syntax works great. However, if I delete a record that is in TABLE B, the above code would in return, insert the deleted record back into TABLE B. I do not want this to happen. Is there another way to insert a record that is NOT IN TABLE B "only once". It should basically ignore all other previously inserted records which were inserted into TABLE B. If it was deleted it should not be inserted a second time.
I want it to only insert only new records added to TABLE A.
If the ID is consecutive integer then you can use:
Insert Into TABLE B
Select id, col, col, col......
From TABLE A
where ID > select(max(id) from table B)

Using ignore_duplicate on non primary key

I've got table:
ID (identity, PK), TaskNr, OfferNr
I want to do insert ignore statement but sadly it's not working on MSSQL, so there's a IGNORE_DUP switch. But I need to check duplicates using TaskNr column. Is there any chance to do that?
Edit:
Sample data:
ID (identity, PK), TaskNr, OfferNr
1 BP1234 XAS
2 BD123 JFRT
3 1122AH JDA33
4 22345_a MD_3
Trying to do:
insert ignore into Sample_table (TaskNr, OfferNr) values (BP1234, DFD,)
Should ignore that row and go to next value of insert statement. ID is autoincremented but unique value should be checked using TaskNr column.
SQL Server does not support insert ignore. That is MySQL functionality.
You can do what you want as:
insert ignore into Sample_table (TaskNr, OfferNr)
select x.TaskNr, x.OfferNr
from (select 'BP1234' as TaskNr, 'DFD' as OfferNr) x
where not exists (select 1
from Sample_Table st
where st.TaskNr = x.TaskNr and st.OfferNr = x.OfferNr
);
You can try two options:
insert into ... where not exists ()
t-sql merge statement (https://learn.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql)

DB2 Using with statement to keep last id

In my project I need to create a script that insert data with auto generate value for the primary key and then to reuse this number for foreign on other tables.
I'm trying to use the WITH statement in order to keep that value.
For instance, I'm trying to do this:
WITH tmp as (SELECT ID FROM (INSERT INTO A ... VALUES ...))
INSERT INTO B ... VALUES tmp.ID ...
But I can't make it work.
Is it at least possible to do it or am I completely wrong???
Thank you
Yes, it is possible, if your DB2-server version supports the syntax.
For example:
create table xemp(id bigint generated always as identity, other_stuff varchar(20));
create table othertab(xemp_id bigint);
SELECT id FROM FINAL TABLE
(INSERT INTO xemp(other_stuff)
values ('a'), ('b'), ('c'), ('d')
) ;
The above snippet of code gives the result below:
ID
--------------------
1
2
3
4
4 record(s) selected.
If you want to re-use the ID to populate another table:
with tmp1(id) as ( SELECT id FROM new TABLE (INSERT INTO xemp(other_stuff) values ('a1'), ('b1'), ('c1'), ('d1') ) tmp3 )
, tmp2 as (select * from new table (insert into othertab(xemp_id) select id from tmp1 ) tmp4 )
select * from othertab;
As per my understanding
You will have to create an auto-increment field with the sequence object (this object generates a number sequence).
You can CREATE SEQUENCE to achieve the auto increment value :
CREATE SEQUENCE seq_person
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 10

SQL Server where condition on column with separated values

I have a table with a column that can have values separated by ",".
Example column group:
id column group:
1 10,20,30
2 280
3 20
I want to create a SELECT with where condition on column group where I can search for example 20 ad It should return 1 and 3 rows or search by 20,280 and it should return 1 and 2 rows.
Can you help me please?
As pointed out in comments,storing mutiple values in a single row is not a good idea..
coming to your question,you can use one of the split string functions from here to split comma separated values into a table and then query them..
create table #temp
(
id int,
columnss varchar(100)
)
insert into #temp
values
(1,'10,20,30'),
(2, '280'),
(3, '20')
select *
from #temp
cross apply
(
select * from dbo.SplitStrings_Numbers(columnss,',')
)b
where item in (20)
id columnss Item
1 10,20,30 20
3 20 20
The short answer is: don't do it.
Instead normalize your tables to at least 3NF. If you don't know what database normalization is, you need to do some reading.
If you absolutely have to do it (e.g. this is a legacy system and you cannot change the table structure), there are several articles on string splitting with TSQL and at least a couple that have done extensive benchmarks on various methods available (e.g. see: http://sqlperformance.com/2012/07/t-sql-queries/split-strings)
Since you only want to search, you don't really need to split the strings, so you can write something like:
SELECT id, list
FROM t
WHERE ','+list+',' LIKE '%,'+#searchValue+',%'
Where t(id int, list varchar(max)) is the table to search and #searchValue is the value you are looking for. If you need to search for more than one value you have to add those in a table and use a join or subquery.
E.g. if s(searchValue varchar(max)) is the table of values to search then:
SELECT distinct t.id, t.list
FROM t INNER JOIN s
ON ','+t.list+',' LIKE '%,'+s.searchValue+',%'
If you need to pass those search values from ADO.Net consider table parameters.

sql conversion script

I have a 2 databases that I want to merge with some similiar tables. The source tables have id as bigint and my destination table has int as ID. There aren't that many records in my source table (< 20k) so I want to assign new ids to all records so the ids can fit in an int. How can I do this with sql?
First Option
You can Use Sequence object as follow:
First Create a Sequence object and assign it's Start With value to max Id value in destination table plus 1. For example if max Id in destination table is 100, you need to assign 101 as Start With. You can also obtain the max Id value from destination table using a Max(Id) aggregate function and store it in a variable:
CREATE SEQUENCE SeqId
START WITH [Max value of Id in destination table]
INCREMENT BY 1 ;
GO
Then insert to destination table using following query:
Insert Into tblXXX (Id, ...) Values (NEXT VALUE FOR SeqId, ...)
Read more about Sequence Object
Second Option
You can make the destination table's Id column as Identity column with seed equal to destination table's Id column max value and Increment equal to 1.
Here is detailed example also Here
You did not provide much details so I can only provide a general guideline:
Note: Example assumes that you want to merge tables A and B into C and you want to generate new IDs. I also assume that these IDs are not referenced by other tables (foreign keys).
First you get record counts from tables A and B:
DECLARE #countA INT
DECLARE #countB INT
SET #countA = ( SELECT COUNT(*) FROM A )
SET #countB = ( SELECT COUNT(*) FROM B )
Next you use a window function to generate new IDs and insert records into table C.
INSERT INTO C
SELECT #countA + ROW_NUMBER() OVER( ORDER BY ID ) AS ID, ....
FROM A
INSERT INTO C
SELECT #countA + #countB + ROW_NUMBER() OVER( ORDER BY ID ) AS ID, ....
FROM B