When there is a 6 month Gap Grab everything after if there is no 6 month gap then grab everything sql - sql

I am working on a query pull and I need some help.
I am trying to figure out a case when statement when there is a 6 month gap then grab the next number when There is no 6 month gap then grab all of them.
Example 1:
ID Gap
1 0
2 4
3 1
4 8
5 1
6 6
7 1
So in this example, there is a gap of 8 so if that was the only gap >= 6 then I would just grab that one but since there is another gap of 6 I just want to grab ID 7.
Example 2:
ID Gap
1 0
2 1
3 0
4 2
5 0
So in this example, there is no gap. so I want to grab all of those IDs.
This is all in sql

Well, you can use window functions:
select id, gap
from (select t.*,
max(case when gap >= 6 then id end) over (order by id) as id_6
from t
) t
where id > id_6 or id_6 is null;

With cursor, didn't test on SSMS. It's another way to do it, not the best but that was for my personal training.
IF EXISTS (SELECT * FROM table WHERE Gap >= 6)
BEGIN
DECLARE #id AS INT;
DECLARE #gap AS INT;
DECLARE #id2 AS INT;
DECLARE #gap2 AS INT;
DECLARE gap_cursor CURSOR FOR
SELECT ID, Gap
FROM table;
OPEN gap_cursor;
FETCH NEXT FROM gap_cursor INTO #id, #gap;
WHILE ##FETCH_STATUS = 0
BEGIN
IF (#gap >= 6)
BEGIN
FETCH NEXT FROM gap_cursor
INTO #id, #gap;
SET #id2 = #id;
SET #gap2 = #gap;
END
ELSE
BEGIN
FETCH NEXT FROM gap_cursor INTO #id, #gap;
END
END
SELECT #id2, #gap2;
END
ELSE
BEGIN
SELECT *
FROM table;
END

Related

loop through rows and delete those with a specific value

I have a question. I have for example this table in database:
row column visible
-----------------------
1 1 no
1 2 no
1 3 no
1 4 no
2 1 yes
2 2 yes
2 3 yes
2 4 yes
I want to loop through this table and to verify if all the rows have visibility "no". If all the row have the visibility no, I want that my new table to be :
row column visible
-----------------------
1 1 yes
1 2 yes
1 3 yes
1 4 yes
I am thinking at a cursor in a stored procedure like this:
create procedure someProcedure
as
declare #visible varchar(5)
declare #column int
declare #position int
declare scan cursor for
select column, position, visible
from table
where row between (select min(row) from table)
and (select max(row) from table)
order by row, column
but i don't know how to do this, I'm very new to sql,thank you
Cursors are slow and inefficient, and are very rarely needed. You don't need a cursor for this, you can use an updatable CTE to update the yes rows.
CREATE OR ALTER PROCEDURE someProcedure
AS
WITH cte AS (
SELECT *,
AnyVisible = COUNT(CASE WHEN Visible = 'yes' THEN 1 END) OVER (PARTITION BY row)
FROM [table] t
)
DELETE FROM cte
WHERE AnyVisible = 0;
WITH cte AS (
SELECT *,
rn = DENSE_RANK() OVER (ORDER BY row)
FROM [table] t
)
UPDATE cte
SET row = rn;
GO
I am not a 100% sure what you are trying to achieve but here is a small template for the cursor.
create procedure someProcedure as
declare #column int
declare #position int
declare #visible varchar(5)
declare scan cursor for
select column, position, visible
from table
where row between (select min(row) from table)
and (select max(row) from table)
order by row, column
--Open the cursor
open scan
-- fill variables with first position of cursor
fetch next from scan into #column, #position, #visible
-- start looping unit end
while(##FETCH_STATUS = 0)
begin
/*
Do things here
*/
-- move to next position in cursor
fetch next from scan into #column, #position, #visible
end
close scan
deallocate scan

Difference between two columns into separate rows for each value between the two

I'm having trouble explaining my problem but I have this table
ID START END
1 10 12
2 30 31
3 11 13
and want something like this:
ID NUMBER
1 10
1 11
1 12
2 30
2 31
3 11
3 12
3 13
I need the all unique whole numbers between the two columns transform into separate rows.
Here's how I want the transformation to look like
I haven't tried anything because I don't even know how to call such procedure so any help is appreciated
If you don't have a numbers table (highly recommended), you can use an ad-hoc tally table in concert with a CROSS APPLY
Example
Select A.ID
,B.Number
From YourTable A
Cross Apply ( Select Top ([End]-[Start]+1)
Number=[START]-1+Row_Number() Over (Order By (Select NULL))
From master..spt_values n1, master..spt_values n2
) B
Returns
ID Number
1 10
1 11
1 12
2 30
2 31
3 11
3 12
3 13
In SQL Server, you can use a recursive CTE:
with cte as (
select id, [start] as number, [end] as end_number
from t
union all
select id, number + 1
from cte
where number < end_number
)
select id, number
from cte;
Note: If the span can exceed 100, you need option (maxrecursion) for the query.
Recursive CTEs are usually a bit slower than a numbers table. However, I find them much faster than I would expect.
--create table NewTable
--(
--ID int,
--NUMBER int
--)
DECLARE #ID nvarchar(50)
declare #START int
declare #END int
DECLARE Cursor_Name CURSOR
FOR
select ID, [START], [End] from tblSequences
OPEN Cursor_Name
FETCH NEXT FROM Cursor_Name INTO #ID,#START,#END
WHILE ##FETCH_STATUS = 0
begin
WHILE #START<=#END
begin
insert into NewTable (ID, NUMBER) Values (#ID, #START)
set #START = #START+1
end
FETCH NEXT FROM Cursor_Name INTO #ID,#START,#END
end
CLOSE Cursor_Name
DEALLOCATE Cursor_Name
select * from NewTable

sql how to get consecutive appearance of value

suppose I have a column 'value', which can appear multiple times in a table with another column 'result' which can be either 1 or 0. I would like to search for consecutive 1s (ie result = 1) until the count reaches 4, then I can select value. given the result sets below:
-result set a)
value Result
----- ------
A 1
A 1
A 1
A 0
-result set b)
value Result
----- ------
A 1
A 1
A 1
A 1
result set b meets the condition and therefore value A is selected. How do I go about this ? Thanks.
This is the query: (usually this query is to detect double record in a table, but probably meet your demand).
select value, result, count(value) as [Result Sum]
from #temp
where result = 1
group by value, result
having count(value) >3
This is the Result
value result Result Sum
----- ----------- -----------
A 1 4
UPDATED:
This is the data example in my temporary table (#temp)
value result
----- -----------
A 1
A 1
A 1
A 0
A 1
D 1
D 1
D 1
D 1
B 1
B 1
C 1
C 1
C 1
C 1
From The example data C and D are the valid values
Declare #temp2 table
(
value nvarchar(5)
)
declare #value nvarchar(5), #result int, #total int, #flag bit, #tempValue nvarchar(5)
DECLARE myCursor CURSOR FOR
SELECT value, result
FROM #temp
set #flag = 1
set #tempValue = ''
OPEN myCursor;
FETCH NEXT FROM myCursor into #value, #result;
WHILE ##FETCH_STATUS = 0
BEGIN
--logic here
if (#tempValue <> #value and #result = 1) or #flag = 1
begin
set #tempValue = #value
set #total = 1
set #flag = 0
end
else --#tempvalue = #value
begin
if #result = 1
set #total = #total + 1
else --#result = 0
set #flag = 1
if #total >3 --valid value has reached 4 consecutive result =1
begin
set #flag = 1
insert into #temp2 values (#value)
end
end
FETCH NEXT FROM myCursor into #value, #result;
END;
CLOSE myCursor;
DEALLOCATE myCursor;
select * from #temp2
This is the Result of the loop (table #temp2)
value
-----
D
C
(2 row(s) affected)
You can do this in a select statement. You can find groups of items in a row by using row_number() assuming you have an id. SQL tables are inherently unordered, so you need an id or creation date or something to specify the ordering. Here is the SQL:
select value
from (select t,
(row_number() over (partition by value order by id) -
row_number() over (partition by value, results order by id)
) as grp
from table t
) t
group by value, result, grp
having count(*) > 3 and result = 1;

How to calculate with sql queries or views

I have a table
id name parentid
----------------
1 a 0
2 b 1
3 c 2
4 d 1
Now I want to calculate level with
if direct parent id count = 6 then level1,
if have 6 level1 count then level2,
if have 6 level2 count then level3, and so on
I am using SQL Server 2005 Express
You have to use sql recursion query may be this help you http://msdn.microsoft.com/en-us/library/ms186243(v=sql.105).aspx
This should do the job: Simply jump to the parent until you reach the top and count the amount of iterations.
create function dbo.CalcLevel (#ID int)
returns int
as
begin
declare #level int=0
while #ID != 0 begin
select #ID=parentID from MyTable where ID=#ID
set #level = #level + 1
if (#level = 1000) set #ID = 0 -- compensate endless loop
end
return #level
end

SQL increment a number

Problem:
I want to increment a number based on a table.
So for example, if a table contains
row
1 1 2 3 4 4 4 5
mytable column should increment based on this taking the max(row) + 1 in the above column. So the outcome should look like this:
6 6 7 8 9 9 9 10
This is the code so far:
OPEN cur
DECLARE #WORKING_ON_ID INT
FETCH NEXT FROM cur INTO #WORKING_ON_ID
WHILE ##FETCH_STATUS = 0
BEGIN
SET #MAX_ID = #MAX_ID + 1
UPDATE
#WorkingTable
SET
ID = #MAX_ID
WHERE
ID = #WORKING_ON_ID
FETCH NEXT FROM cur INTO #WORKING_ON_ID
END
CLOSE cur
DEALLOCATE cur
Could you please help me in getting a solution to this problem.
Thanks!
I think you could do it easily with this:
UPDATE your_table
SET id = id + (SELECT MAX(id) FROM your_table)
Wouldn't it be easier to just take the maximum and add it to this ID column? (Remember: the ID column can't be an identity column, otherwise an update will fail)
DECLARE #MAXID INT
SELECT #MAXID = MAX(ID) FROM #WorkingTable
UPDATE #WorkingTable SET ID = ID + #MAXID
Please Try this Code:
Declare #count int = 0
UPDATE table
SET #count = code = #count + 1
Why use a cursor? Wouldn't this solve your problem as well:
DECLARE #MAXID int
SELECT #MAXID=MAX(ID) FROM YourTable
UPDATE YourTable SET ID = ID + #MAXID
In SQL Server 2005 or later version:
WITH cte AS (
SELECT ID, MAX(ID) OVER () AS delta FROM atable
)
UPDATE cte
SET ID = ID + delta;