SQL sum based on the result - sql

pre qty cur
--------------------
100 -1 99
99 -10 89
89 10 99
Hi, I would like to update the column pre, qty, cur. I tried to sum pre and qty then result cur will bring to the next pre column for continue the calculation.
So far this is my query.
SELECT `id`, `pre` , `qty`, `cur`, `pre`+`qty` AS `cur` FROM `inventory_logs`

If that is your desired output at the top of your question, you can use LAG to update your table in one shot instead of processing one cur at a time:
UPDATE inventory_logs
SET cur = pr.P
FROM inventory_logs JOIN (SELECT pre, qty, LAG(pre + qty, 0)
OVER (Partition by pre ORDER BY id asc) AS P
FROM inventory_logs) as pr
ON inventory_logs.pre = pr.pre;

From what I understand you have posted the expected results in your question.
You can use a recursive CTE:
WITH CTE AS(
SELECT ID,PRE,QTY,PRE+QTY AS CUR FROM inventory_logs WHERE ID=1
UNION ALL
SELECT T.ID, C.CUR AS PRE, T.QTY, C.CUR + T.QTY AS CUR
FROM CTE C
INNER JOIN inventory_logs T
ON T.ID = C.ID+1
)
SELECT * FROM CTE
Assuming ofcourse you want to start the calculation from ID =1 and are ordering by ID

Try it in sql,
UPDATE inventory_logs SET cur=pre + qty
SELECT id, pre , qty, cur FROM inventory_logs

Related

In SQL Server, how to create while loop

I Have the following :
I used the select to got the Id from table as follow :
Select Id from t
data will be like this:
id
DG1
FS2
DD4
I want to pass result the result to the following sql statement using while or case
Depend of the result of the select statement
SELECT f.age_days, f.Body_wt,f.Act_Fcr_Day,f.Act_Growth ,
f.growth_gm as Growth ,f2.growth_gm as Growth1,
COALESCE(
(
SELECT TOP 1 Body_wt
FROM [dbo].[Broiler_Farms_Data] mi
WHERE mi.Age_Days > f.Age_Days and mi.flock_id = ??????
ORDER BY
Age_Days
), 0) - f.Body_wt AS diff
FROM [dbo].[Broiler_Farms_Data] f
How can I do it .
thanks
I find this type of logic easier to follow with outer apply:
SELECT f.age_days, f.Body_wt, f.Act_Fcr_Day, f.Act_Growth,
f.growth_gm as Growth, f2.growth_gm as Growth1,
(COALESCE(mi.Body_wt, 0) - f.Body_wt0 AS diff
FROM [dbo].[Broiler_Farms_Data] f OUTER APPLY
(SELECT TOP 1 mi.*
FROM [dbo].[Broiler_Farms_Data] mi
WHERE mi.Age_Days > f.Age_Days and mi.flock_id = ??????
ORDER BY mi.Age_Days
) mi;
Then, if I understand correctly:
SELECT t.id, f.age_days, f.Body_wt, f.Act_Fcr_Day, f.Act_Growth,
f.growth_gm as Growth, f2.growth_gm as Growth1,
(COALESCE(mi.Body_wt, 0) - f.Body_wt0 AS diff
FROM [dbo].[Broiler_Farms_Data] f CROSS JOIN
(Select Id from t
) t OUTER APPLY
(SELECT TOP 1 mi.*
FROM [dbo].[Broiler_Farms_Data] mi
WHERE mi.Age_Days > f.Age_Days and mi.flock_id = t.id
ORDER BY mi.Age_Days
) mi;
This also includes the id in the SELECT, because that seems desirable.
Aggregate functions in VARCHAR columns are not advised. If you have a Primary Key or a surrogate key which can be used, then it will be helpful. Use the below query to use WHILE LOOP.
DECLARE #Id VARCHAR(10) = ''
WHILE 1=1
BEGIN
SELECT #Id = MIN(Id) from t WHERE Id > #Id
IF #Id IS NULL
BREAK
SELECT f.age_days, f.Body_wt,f.Act_Fcr_Day,f.Act_Growth ,
f.growth_gm as Growth ,f2.growth_gm as Growth1,
COALESCE(
(
SELECT TOP 1 Body_wt
FROM [dbo].[Broiler_Farms_Data] mi
WHERE mi.Age_Days > f.Age_Days and mi.flock_id = #Id
ORDER BY
Age_Days
), 0) - f.Body_wt AS diff
FROM [dbo].[Broiler_Farms_Data] f
END

Update table with another column in the same table

I have a table like this
Test_order
Order Num Order ID Prev Order ID
987Y7OP89 919325 0
987Y7OP90 1006626 919325
987Y7OP91 1029350 1006626
987Y7OP92 1756689 0
987Y7OP93 1756690 0
987Y7OP94 1950100 1756690
987Y7OP95 1977570 1950100
987Y7OP96 2160462 1977570
987Y7OP97 2288982 2160462
Target table should be like below,
Order Num Order ID Prev Order ID
987Y7OP89 919325 0
987Y7OP90 1006626 919325
987Y7OP91 1029350 1006626
987Y7OP92 1756689 1029350
987Y7OP93 1756690 1756689
987Y7OP94 1950100 1756690
987Y7OP95 1977570 1950100
987Y7OP96 2160462 1977570
987Y7OP97 2288982 2160462
987Y7OP97 2288900 2288982
Prev Order ID should be updated with the Order ID from the previous record from the same table.
I'm trying to create a dummy data set and update..but it's not working..
WITH A AS
(SELECT ORDER_NUM, ORDER_ID, PRIOR_ORDER_ID,ROWNUM RID1 FROM TEST_ORDER),B AS (SELECT ORDER_NUM, ORDER_ID, PRIOR_ORDER_ID,ROWNUM+1 RID2 FROM TEST_ORDER)
SELECT A.ORDER_NUM,B.ORDER_ID,A.PRIOR_ORDER_ID,B.PRIOR_ORDER_ID FROM A,B WHERE RID1 = RID2
You could use Oracles Analytical Functions (also called Window functions) to pick up the value from the previous order:
UPDATE Test_Order
SET ORDERID = LAG(ORDERID, 1, 0) OVER (ORDER BY ORDERNUM ASC)
WHERE PrevOrderId = 0
See here for the documentation on LAG()
In sql-server you cannot use window function in update statement, not positive but don't think so in Oracle either. Anyway to get around that you can just update a cte as follows.
WITH cte AS (
SELECT
*
,NewPreviousOrderId = LAG(OrderId,1,0) OVER (ORDER BY OrderNum)
FROM
TableName
)
UPDATE cte
SET PrevOrderId = NewPreviousOrderId
And if you want to stick with the ROW_NUMBER route you were going this would be the way of doing it.
;WITH cte AS (
SELECT
*
,ROW_NUMBER() OVER (ORDER BY OrderNum) AS RowNum
FROM
TableName
)
UPDATE c1
SET PrevOrderId = c2.OrderId
FROM
cte c1
INNER JOIN cte c2
ON (c1.RowNum - 1) = c2.RowNum

Efficiently writing this formula in SQL server 2008

Say I have table and these are its sample rows
ChangeID Change
1 102
2 105
3 107
4 110
The change formula is
(CurrentRowChange - PreviousRowChange) / PreviousRowChange
Hence:
for 1st row it should be 0
for 2nd row it should be (105 - 102) / 102
and so on. How can I efficiently write this formula in SQL?
I know I can write a scalar function and then do a RowNumber and order By ChangeID and fetch the row number's Change value and then find the current row number - 1 and then fetch that row's Change value and do a divide.
Is there any better way to achieve this?
give this a try, assuming that CHANGEID can be deleted and it is IDENTITY.
WITH changeList
AS
(
SELECT ChangeID, [Change],
(ROW_NUMBER() OVER (ORDER BY ChangeID ASC)) -1 AS rn
FROM TableName
),
normalList
AS
(
SELECT ChangeID, [Change],
(ROW_NUMBER() OVER (ORDER BY ChangeID ASC)) AS rn
FROM TableName
)
SELECT a.ChangeID, a.[Change],
COALESCE((a.Change - b.change) / (b.change * 1.0),0) result
FROM changeList a
LEFT JOIN normalList b
ON a.rn = b.rn
SQLFiddle Demo
select cur.*
, case
when prev.ChangeId is null then 0
else 1.0 * (cur.Change - prev.Change) / prev.Change
end
from Table1 cur
left join
Table1 prev
on cur.ChangeId = prev.ChangeId + 1
SQL Fiddle example.
While the ChangeID's are sequential in the sample, I wouldn't assume that they always are. So I would do something like this:
with RankedIDs as
select ChangeID
, Change
, rank() over
(partition by ChangeID order by ChangeId) rank
where something maybe ;
select case
when r1.rank = 1 then 0
else (r1.change - r2.change) / r2.change
end SomeName
from RankedIds r1 join RankedIds r2 on r1.rank = r2.rank + 1
That's the basic idea. You might want to add divide by zero protection
select T1.ChangeID,
(1.0 * T1.Change / T2.Change) - 1 as Result
from TableName as T1
outer apply (
select top(1) T.Change
from TableName as T
where T.ChangeID < T1.ChangeID
order by T.ChangeID desc
) as T2

how do i get multiple records from 1 record

I have a product table with 15 fields like ItemID (primary),Name ,UPC,Price,Cost, etc.
Now I need to print labels the user can say
from Item "ABC" I need 15 labels
from item 'XYZ" I need 10 labels
I need a SQL statement which I will send the ItemID and the label Qty for Each record and it should give me back for each label a record for example 15 records for item "ABC" and 10 records for Item "XYZ" and so on
SELECT <fields>
FROM Mytable
Where Item = 'ABC'
GO 10
Will select those fields from that table 10 times in a row in 10 result sets.
Really though it sounds like you need to do what you are trying to do not in SQL, but in your calling application.
I agree this should be done on the client but if you insist, following duplicates each record 100 times and selects the amount you need from it.
;WITH ATable AS (
SELECT Item = 'ABC'
UNION ALL SELECT Item = 'XYZ'
)
, Temp (Item, Amount) AS (
SELECT 'ABC', 15
UNION ALL SELECT 'XYZ', 10
)
, q AS (
SELECT ID = 1
, Item
FROM ATable
UNION ALL
SELECT ID = q.ID +1
, q.Item
FROM q
WHERE ID < 100
)
SELECT q.*
FROM q
INNER JOIN Temp t ON t.Item = q.Item
AND t.Amount >= q.ID
You create the dynamic table aliased as r below. Works for amounts up to 2047.
select t.*
from
(select label='ABC', required=15 union all
select label='XYZ', required=10) r
inner join tbl t
on t.ItemID = r.label
inner join master..spt_values v
on v.type=Number and v.number between 1 and r.required
order by t.ItemID

How do I find a "gap" in running counter with SQL?

I'd like to find the first "gap" in a counter column in an SQL table. For example, if there are values 1,2,4 and 5 I'd like to find out 3.
I can of course get the values in order and go through it manually, but I'd like to know if there would be a way to do it in SQL.
In addition, it should be quite standard SQL, working with different DBMSes.
In MySQL and PostgreSQL:
SELECT id + 1
FROM mytable mo
WHERE NOT EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.id = mo.id + 1
)
ORDER BY
id
LIMIT 1
In SQL Server:
SELECT TOP 1
id + 1
FROM mytable mo
WHERE NOT EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.id = mo.id + 1
)
ORDER BY
id
In Oracle:
SELECT *
FROM (
SELECT id + 1 AS gap
FROM mytable mo
WHERE NOT EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.id = mo.id + 1
)
ORDER BY
id
)
WHERE rownum = 1
ANSI (works everywhere, least efficient):
SELECT MIN(id) + 1
FROM mytable mo
WHERE NOT EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.id = mo.id + 1
)
Systems supporting sliding window functions:
SELECT -- TOP 1
-- Uncomment above for SQL Server 2012+
previd
FROM (
SELECT id,
LAG(id) OVER (ORDER BY id) previd
FROM mytable
) q
WHERE previd <> id - 1
ORDER BY
id
-- LIMIT 1
-- Uncomment above for PostgreSQL
Your answers all work fine if you have a first value id = 1, otherwise this gap will not be detected. For instance if your table id values are 3,4,5, your queries will return 6.
I did something like this
SELECT MIN(ID+1) FROM (
SELECT 0 AS ID UNION ALL
SELECT
MIN(ID + 1)
FROM
TableX) AS T1
WHERE
ID+1 NOT IN (SELECT ID FROM TableX)
There isn't really an extremely standard SQL way to do this, but with some form of limiting clause you can do
SELECT `table`.`num` + 1
FROM `table`
LEFT JOIN `table` AS `alt`
ON `alt`.`num` = `table`.`num` + 1
WHERE `alt`.`num` IS NULL
LIMIT 1
(MySQL, PostgreSQL)
or
SELECT TOP 1 `num` + 1
FROM `table`
LEFT JOIN `table` AS `alt`
ON `alt`.`num` = `table`.`num` + 1
WHERE `alt`.`num` IS NULL
(SQL Server)
or
SELECT `num` + 1
FROM `table`
LEFT JOIN `table` AS `alt`
ON `alt`.`num` = `table`.`num` + 1
WHERE `alt`.`num` IS NULL
AND ROWNUM = 1
(Oracle)
The first thing that came into my head. Not sure if it's a good idea to go this way at all, but should work. Suppose the table is t and the column is c:
SELECT
t1.c + 1 AS gap
FROM t as t1
LEFT OUTER JOIN t as t2 ON (t1.c + 1 = t2.c)
WHERE t2.c IS NULL
ORDER BY gap ASC
LIMIT 1
Edit: This one may be a tick faster (and shorter!):
SELECT
min(t1.c) + 1 AS gap
FROM t as t1
LEFT OUTER JOIN t as t2 ON (t1.c + 1 = t2.c)
WHERE t2.c IS NULL
This works in SQL Server - can't test it in other systems but it seems standard...
SELECT MIN(t1.ID)+1 FROM mytable t1 WHERE NOT EXISTS (SELECT ID FROM mytable WHERE ID = (t1.ID + 1))
You could also add a starting point to the where clause...
SELECT MIN(t1.ID)+1 FROM mytable t1 WHERE NOT EXISTS (SELECT ID FROM mytable WHERE ID = (t1.ID + 1)) AND ID > 2000
So if you had 2000, 2001, 2002, and 2005 where 2003 and 2004 didn't exist, it would return 2003.
The following solution:
provides test data;
an inner query that produces other gaps; and
it works in SQL Server 2012.
Numbers the ordered rows sequentially in the "with" clause and then reuses the result twice with an inner join on the row number, but offset by 1 so as to compare the row before with the row after, looking for IDs with a gap greater than 1. More than asked for but more widely applicable.
create table #ID ( id integer );
insert into #ID values (1),(2), (4),(5),(6),(7),(8), (12),(13),(14),(15);
with Source as (
select
row_number()over ( order by A.id ) as seq
,A.id as id
from #ID as A WITH(NOLOCK)
)
Select top 1 gap_start from (
Select
(J.id+1) as gap_start
,(K.id-1) as gap_end
from Source as J
inner join Source as K
on (J.seq+1) = K.seq
where (J.id - (K.id-1)) <> 0
) as G
The inner query produces:
gap_start gap_end
3 3
9 11
The outer query produces:
gap_start
3
Inner join to a view or sequence that has a all possible values.
No table? Make a table. I always keep a dummy table around just for this.
create table artificial_range(
id int not null primary key auto_increment,
name varchar( 20 ) null ) ;
-- or whatever your database requires for an auto increment column
insert into artificial_range( name ) values ( null )
-- create one row.
insert into artificial_range( name ) select name from artificial_range;
-- you now have two rows
insert into artificial_range( name ) select name from artificial_range;
-- you now have four rows
insert into artificial_range( name ) select name from artificial_range;
-- you now have eight rows
--etc.
insert into artificial_range( name ) select name from artificial_range;
-- you now have 1024 rows, with ids 1-1024
Then,
select a.id from artificial_range a
where not exists ( select * from your_table b
where b.counter = a.id) ;
This one accounts for everything mentioned so far. It includes 0 as a starting point, which it will default to if no values exist as well. I also added the appropriate locations for the other parts of a multi-value key. This has only been tested on SQL Server.
select
MIN(ID)
from (
select
0 ID
union all
select
[YourIdColumn]+1
from
[YourTable]
where
--Filter the rest of your key--
) foo
left join
[YourTable]
on [YourIdColumn]=ID
and --Filter the rest of your key--
where
[YourIdColumn] is null
For PostgreSQL
An example that makes use of recursive query.
This might be useful if you want to find a gap in a specific range
(it will work even if the table is empty, whereas the other examples will not)
WITH
RECURSIVE a(id) AS (VALUES (1) UNION ALL SELECT id + 1 FROM a WHERE id < 100), -- range 1..100
b AS (SELECT id FROM my_table) -- your table ID list
SELECT a.id -- find numbers from the range that do not exist in main table
FROM a
LEFT JOIN b ON b.id = a.id
WHERE b.id IS NULL
-- LIMIT 1 -- uncomment if only the first value is needed
My guess:
SELECT MIN(p1.field) + 1 as gap
FROM table1 AS p1
INNER JOIN table1 as p3 ON (p1.field = p3.field + 2)
LEFT OUTER JOIN table1 AS p2 ON (p1.field = p2.field + 1)
WHERE p2.field is null;
I wrote up a quick way of doing it. Not sure this is the most efficient, but gets the job done. Note that it does not tell you the gap, but tells you the id before and after the gap (keep in mind the gap could be multiple values, so for example 1,2,4,7,11 etc)
I'm using sqlite as an example
If this is your table structure
create table sequential(id int not null, name varchar(10) null);
and these are your rows
id|name
1|one
2|two
4|four
5|five
9|nine
The query is
select a.* from sequential a left join sequential b on a.id = b.id + 1 where b.id is null and a.id <> (select min(id) from sequential)
union
select a.* from sequential a left join sequential b on a.id = b.id - 1 where b.id is null and a.id <> (select max(id) from sequential);
https://gist.github.com/wkimeria/7787ffe84d1c54216f1b320996b17b7e
Here is an alternative to show the range of all possible gap values in portable and more compact way :
Assume your table schema looks like this :
> SELECT id FROM your_table;
+-----+
| id |
+-----+
| 90 |
| 103 |
| 104 |
| 118 |
| 119 |
| 120 |
| 121 |
| 161 |
| 162 |
| 163 |
| 185 |
+-----+
To fetch the ranges of all possible gap values, you have the following query :
The subquery lists pairs of ids, each of which has the lowerbound column being smaller than upperbound column, then use GROUP BY and MIN(m2.id) to reduce number of useless records.
The outer query further removes the records where lowerbound is exactly upperbound - 1
My query doesn't (explicitly) output the 2 records (YOUR_MIN_ID_VALUE, 89) and (186, YOUR_MAX_ID_VALUE) at both ends, that implicitly means any number in both of the ranges hasn't been used in your_table so far.
> SELECT m3.lowerbound + 1, m3.upperbound - 1 FROM
(
SELECT m1.id as lowerbound, MIN(m2.id) as upperbound FROM
your_table m1 INNER JOIN your_table
AS m2 ON m1.id < m2.id GROUP BY m1.id
)
m3 WHERE m3.lowerbound < m3.upperbound - 1;
+-------------------+-------------------+
| m3.lowerbound + 1 | m3.upperbound - 1 |
+-------------------+-------------------+
| 91 | 102 |
| 105 | 117 |
| 122 | 160 |
| 164 | 184 |
+-------------------+-------------------+
select min([ColumnName]) from [TableName]
where [ColumnName]-1 not in (select [ColumnName] from [TableName])
and [ColumnName] <> (select min([ColumnName]) from [TableName])
Here is standard a SQL solution that runs on all database servers with no change:
select min(counter + 1) FIRST_GAP
from my_table a
where not exists (select 'x' from my_table b where b.counter = a.counter + 1)
and a.counter <> (select max(c.counter) from my_table c);
See in action for;
PL/SQL via Oracle's livesql,
MySQL via sqlfiddle,
PostgreSQL via sqlfiddle
MS Sql via sqlfiddle
It works for empty tables or with negatives values as well. Just tested in SQL Server 2012
select min(n) from (
select case when lead(i,1,0) over(order by i)>i+1 then i+1 else null end n from MyTable) w
If You use Firebird 3 this is most elegant and simple:
select RowID
from (
select `ID_Column`, Row_Number() over(order by `ID_Column`) as RowID
from `Your_Table`
order by `ID_Column`)
where `ID_Column` <> RowID
rows 1
-- PUT THE TABLE NAME AND COLUMN NAME BELOW
-- IN MY EXAMPLE, THE TABLE NAME IS = SHOW_GAPS AND COLUMN NAME IS = ID
-- PUT THESE TWO VALUES AND EXECUTE THE QUERY
DECLARE #TABLE_NAME VARCHAR(100) = 'SHOW_GAPS'
DECLARE #COLUMN_NAME VARCHAR(100) = 'ID'
DECLARE #SQL VARCHAR(MAX)
SET #SQL =
'SELECT TOP 1
'+#COLUMN_NAME+' + 1
FROM '+#TABLE_NAME+' mo
WHERE NOT EXISTS
(
SELECT NULL
FROM '+#TABLE_NAME+' mi
WHERE mi.'+#COLUMN_NAME+' = mo.'+#COLUMN_NAME+' + 1
)
ORDER BY
'+#COLUMN_NAME
-- SELECT #SQL
DECLARE #MISSING_ID TABLE (ID INT)
INSERT INTO #MISSING_ID
EXEC (#SQL)
--select * from #MISSING_ID
declare #var_for_cursor int
DECLARE #LOW INT
DECLARE #HIGH INT
DECLARE #FINAL_RANGE TABLE (LOWER_MISSING_RANGE INT, HIGHER_MISSING_RANGE INT)
DECLARE IdentityGapCursor CURSOR FOR
select * from #MISSING_ID
ORDER BY 1;
open IdentityGapCursor
fetch next from IdentityGapCursor
into #var_for_cursor
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = '
DECLARE #LOW INT
SELECT #LOW = MAX('+#COLUMN_NAME+') + 1 FROM '+#TABLE_NAME
+' WHERE '+#COLUMN_NAME+' < ' + cast( #var_for_cursor as VARCHAR(MAX))
SET #SQL = #sql + '
DECLARE #HIGH INT
SELECT #HIGH = MIN('+#COLUMN_NAME+') - 1 FROM '+#TABLE_NAME
+' WHERE '+#COLUMN_NAME+' > ' + cast( #var_for_cursor as VARCHAR(MAX))
SET #SQL = #sql + 'SELECT #LOW,#HIGH'
INSERT INTO #FINAL_RANGE
EXEC( #SQL)
fetch next from IdentityGapCursor
into #var_for_cursor
END
CLOSE IdentityGapCursor;
DEALLOCATE IdentityGapCursor;
SELECT ROW_NUMBER() OVER(ORDER BY LOWER_MISSING_RANGE) AS 'Gap Number',* FROM #FINAL_RANGE
Found most of approaches run very, very slow in mysql. Here is my solution for mysql < 8.0. Tested on 1M records with a gap near the end ~ 1sec to finish. Not sure if it fits other SQL flavours.
SELECT cardNumber - 1
FROM
(SELECT #row_number := 0) as t,
(
SELECT (#row_number:=#row_number+1), cardNumber, cardNumber-#row_number AS diff
FROM cards
ORDER BY cardNumber
) as x
WHERE diff >= 1
LIMIT 0,1
I assume that sequence starts from `1`.
If your counter is starting from 1 and you want to generate first number of sequence (1) when empty, here is the corrected piece of code from first answer valid for Oracle:
SELECT
NVL(MIN(id + 1),1) AS gap
FROM
mytable mo
WHERE 1=1
AND NOT EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.id = mo.id + 1
)
AND EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.id = 1
)
DECLARE #Table AS TABLE(
[Value] int
)
INSERT INTO #Table ([Value])
VALUES
(1),(2),(4),(5),(6),(10),(20),(21),(22),(50),(51),(52),(53),(54),(55)
--Gaps
--Start End Size
--3 3 1
--7 9 3
--11 19 9
--23 49 27
SELECT [startTable].[Value]+1 [Start]
,[EndTable].[Value]-1 [End]
,([EndTable].[Value]-1) - ([startTable].[Value]) Size
FROM
(
SELECT [Value]
,ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY [Value]) Record
FROM #Table
)AS startTable
JOIN
(
SELECT [Value]
,ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY [Value]) Record
FROM #Table
)AS EndTable
ON [EndTable].Record = [startTable].Record+1
WHERE [startTable].[Value]+1 <>[EndTable].[Value]
If the numbers in the column are positive integers (starting from 1) then here is how to solve it easily. (assuming ID is your column name)
SELECT TEMP.ID
FROM (SELECT ROW_NUMBER() OVER () AS NUM FROM 'TABLE-NAME') AS TEMP
WHERE ID NOT IN (SELECT ID FROM 'TABLE-NAME')
ORDER BY 1 ASC LIMIT 1
SELECT ID+1 FROM table WHERE ID+1 NOT IN (SELECT ID FROM table) ORDER BY 1;