How do I auto increment my own results column from a max value in a table? - sql

select MAX (cast (id as numeric)) from table --whatever value it may return
select
(row_number () over (order by id)) as Number from table --will start at 1
How do I combine the two so whatever value the first query returns, I can use that value and auto increment from there, somehow combining the two (tried nesting them, but unsuccessful) or do I need to...
Declare a variable
get my max id value
make my variable equal to that
then place that value/variable in my second statement?
Like...
select
(row_number () over (order by id) + (declared_max_value)) as Number from table

Try this:
WITH CTE as
(SELECT max(Field) FROM Table)
SELECT WhatYouWant, cte.m FROM Table2
INNER JOIN CTE ON 0=0
or this:
SELECT *, t.maxField FROM Table1 OUTER APPLY (SELECT max(Field) as maxField FROM Table2) t

Try this:
SELECT
Seed.ID + ROW_NUMBER() OVER (order by T.ID) as Number,
T.ID
FROM
T CROSS JOIN
(SELECT MAX(ID) AS ID FROM T) AS Seed
Working sample: http://www.sqlfiddle.com/#!3/a14ad/3

declare #maxValue int
select #maxValue = select max(cast (id as integer)) from table
declare #uaerystring varchar(max)
select #queryString =
'(row_number () over (order by id) + '
+ #maxValue +
')as Number from table'
Execute(#queryString)

DECLARE #T Table (ID int , Value Varchar(20))
INSERT INTO #T (ID, Value)
VALUES (50, 'Value1'), (500, 'Value1'), (100, 'Value1'), (50, 'Value2'), (100, 'Value2'),(500, 'Value2')
;with CTE (Value, ID, rn)
AS
(
SELECT Value, MAX(ID), rn = ROW_NUMBER() OVER (ORDER BY Value ASC)
FROM
#T
GROUP BY Value
)
SELECT * FROM CTE

Related

How to complete and fill in gaps between dates in SQL?

I have data in Redshift that I'm aggregating to the Year-Quarter level i.e. number of items by Year-Quarter
I need to show a continuous trend and hence I need to fill-in the gaps in Year-Quarter. The picture below should give a clearer idea of my current data and desired output.
How can I achieve this in Redshift SQL?
A query like this should do the trick:
create table test (yq int, items int);
INSERT INTO test Values (20201,10),(20204, 15),(20213, 25),(20222, 30);
with recursive quarters(q) as (
select min(yq) as q
from test
union all
select decode(right(q::text, 1), 4, q + 7, q + 1) as q
from quarters
where q < (select max(yq) from test)
)
select q as yq, decode(items is null, true,
lag(items ignore nulls) over (order by q), items) as items
from test t
right join quarters q
on t.yq = q.q
order by q;
It uses a recursive CTE to generate the quarters range needed, right joins this with the source data, and then uses a LAG() window function to populate the items if the value is NULL.
This is known as forward filling values:
CREATE TABLE #Temp
(
[YQ] nvarchar(5),
[items] int
)
INSERT INTO #Temp Values ('20201',10),('20204', 15),('20213', 25),('20222', 30)
---------------------------------------------------------------------------------
DECLARE #start int, #end int, #starty int, #endy int
SELECT #start=1, #end=4
SELECT #starty=MIN(Substring(YQ,0,5)), #endy=MIN(Substring(YQ,0,5)) from #Temp
;With cte1(y) as
(
Select #starty as y
union all
Select y + 1
from cte1
where y <= #endy + 1
)
, cte2(n) as
(
Select #start as n
union all
Select n + 1
from cte2
where n < #end
)
SELECT t1.YQ AS 'Year-Quarter',
CASE WHEN t2.items is null then (SELECT TOP 1 MAX(items) from #Temp WHERE items is not null and YQ < t1.YQ) ELSE t2.items END AS '# Items'
FROM
(
SELECT CAST(cte1.y AS nvarchar(4)) + CAST(cte2.n AS nvarchar(1)) AS YQ
FROM cte1, cte2
) t1
LEFT JOIN #Temp t2 ON t2.YQ = t1.YQ
WHERE t1.YQ <= (SELECT MAX(YQ) FROM #Temp)
ORDER BY t1.YQ, t2.items

Find the missing group entry in sql server

I have the below table:
Declare #t table (Name nvarchar(80))
Insert into #t values
('ABC:CE')
,('ABC:LI')
,('ABC:XP')
,('ABD:CE')
,('ABD:LI')
,('ABE:LI')
,('ABE:XP')
,('ABF:XP')
I have 3 categories CE,LI,XP. I wanted to check which group is missing in the name.
I tried below Query:
select SUBSTRING(Name,1,charindex(':',Name)-1),count(1) as grplist from #t
group by SUBSTRING(Name,1,charindex(':',Name)-1)
having count(1) <3
Expected output:
Name
ABD:XP
ABE:CE
ABF:LI
ABF:CE
Can you guys help me where I am going wrong this:
Try this:
Declare #t table (Name nvarchar(80))
Insert into #t values
('ABC:CE')
,('ABC:LI')
,('ABC:XP')
,('ABD:CE')
,('ABD:LI')
,('ABE:LI')
,('ABE:XP')
,('ABF:XP');
WITH DataSource ([group], [category]) AS
(
SELECT SUBSTRING([Name], 1, CHARINDEX(':', [Name]) - 1)
,SUBSTRING([Name], CHARINDEX(':', [Name]) + 1, 100)
FROM #t
)
SELECT DISTINCT G.[group], C.[category]
FROM DataSource G
CROSS APPLY
(
SELECT DISTINCT [category]
FROM DataSource
) C
WHERE NOT EXISTS
(
SELECT 1
FROM DataSource DS
WHERE DS.[group] = G.[group]
AND DS.[category] = C.[category]
)
You want to select the values that are not in the table. For this to happen, you must first create these values. You do this with a cross join:
select n.name + ':' + c.category as missing
from (select distinct substring(name, 1, charindex(':', name) - 1) as name from #t) n
cross join (values ('CE'), ('LI'), ('XP')) c(category)
except
select name from #t
order by missing;
Demo: http://www.sqlfiddle.com/#!18/c99228/4
I see there's an answer here already but here's my take, looks similar mine may be less efficient but hey more the merrier :)
Declare #t table (Name nvarchar(80))
Insert into #t values
('ABC:CE')
,('ABC:LI')
,('ABC:XP')
,('ABD:CE')
,('ABD:LI')
,('ABE:LI')
,('ABE:XP')
,('ABF:XP')
Declare #c table (Cat nvarchar(2))
Insert into #c values
('CE')
,('LI')
,('XP')
SELECT
possible.prefix
,possible.Cat
,possible.prefix + ':' + possible.Cat
--,selector.Prefix
--,selector.suffix
FROM
(
select
SUBSTRING(Name,1,charindex(':',Name)-1) as prefix
,SUBSTRING(Name,charindex(':',Name)+1,2) as suffix
from #t
) as selector
right Join
(
SELECT DISTINCT
SUBSTRING(Name,1,charindex(':',Name)-1) as prefix
-- ,SUBSTRING(Name,charindex(':',Name)+1,2) as suffix
,Cat
FROM #t
cross join #c
) possible
ON selector.prefix = possible.prefix
and selector.suffix = possible.Cat
where selector.suffix is null

Get a specific string

It's my data and every ThroughRouteSid record has the same pattern.
six number and five comma. then I just want to get three and five
number into two record to template Table and get the same Count()
value to these two record.
For example: First record in the picture.
ThroughRouteSid(3730,2428,2428,3935,3935,3938,) Count(32).
I want a result like this:
2428 32 3935 32
I get What number I want.become two record and both have same Count value into template table
you can use XML to get your result, please refer below sample code -
create table #t1( ThroughRouteSid varchar(500) , Cnt int)
insert into #t1
select '3730,2428,2428,3935,3935,3938,' , len('3730,2428,2428,3935,3935,3938,')
union all select '1111,2222,3333,4444,5555,6666,' , len('1111,2222,3333,4444,5555,6666,')
select cast( '<xml><td>' + REPLACE( SUBSTRING(ThroughRouteSid ,1 , len(ThroughRouteSid)-1),',','</td><td>') + '</td></xml>' as xml) XmlData , Cnt
into #t2 from #t1
select XmlData.value('(xml/td)[3]' ,'int' ), Cnt ,XmlData.value('(xml/td)[5]' ,'int' ), Cnt
from #t2
First create the function referring How to Split a string by delimited char in SQL Server. Then try Querying the following
select (SELECT CONVERT(varchar,splitdata) + ' '+ Convert(varchar, [Count])+' ' FROM (select splitdata, ROW_NUMBER() over (ORDER BY (SELECT 100)) row_no
from [dbo].[fnSplitString](ThroughRouteSid,',')
where splitdata != '') as temp where row_no in (2,5)
for xml path('')) as col1 from [yourtable]
If you are using SQL Server 2016 you can do something like this:
create table #temp (ThroughRouteSid varchar(1024),[Count] int)
insert into #temp values
('3730,2428,2428,3935,3935,3938,',32),
('730,428,428,335,935,938,',28)
select
spt.value,
t.[Count]
from #temp t
cross apply (
select value from STRING_SPLIT(t.ThroughRouteSid,',') where LEN(value) > 0
)spt

Insert two or more Comma separated values in table using sql

I want try to insert Two variable in table the value is separated with comma but i don't know how i can insert it
My situation is below
I create temp table
create table #temp (sku varchar(10), qty int)
now declare two variable with value
declare #sku varchar(200) = 'RCLET0005,RCLET0015';
declare #qty varchar(100) = '2,1';
now i want insert this variable in #temp table
I have split function.
I tried Below query
insert into #temp (sku,qty) values
((select value from [dbo].[fn_Split](#sku, ',')),
(select value from [dbo].[fn_Split](#qty, ',')))
Your fn_Split function needs to return the ordinal position of each value so that the separate lists can be correlated. Below is an example using a derived table subquery. You could also use CTEs or CROSS APPLY.
INSERT INTO #temp (sku,qty)
SELECT
sku.value
, qty.value
FROM (SELECT ordinal_position, value FROM [dbo].[fn_Split](#sku, ',') AS sku
JOIN (SELECT ordinal_position, value FROM [dbo].[fn_Split](#qty, ',') AS qty ON
sku.ordinal_position = qty.ordinal_position;
You could do something like this..
WITH cte AS
(
SELECT ROW_NUMBER() OVER(ORDER BY null) as rn, value FROM [dbo].[fn_Split](#sku, ',')
UNION
SELECT 2+(row_number() OVER(ORDER BY null)) as rn, value FROM [dbo].[fn_Split](#qty, ',')
)
INSERT INTO #temp
SELECT c1.value,c2.value
FROM cte c1
INNER JOIN cte c2 ON c2.rn = c1.rn+1 AND c1.rn IN (1,3) AND c2.rn IN (2,4)
Assuming the values are not repeated in each string and your split function doesn't return the position, you can do:
with s as (
select value,
row_number() over (order by (select null)) as pos
from dbo.fn_Split(#sku, ',')
),
q as (
select value,
row_number() over (order by (select null)) as pos
from dbo.fn_Split(#qty, ',')
)
insert into #temp (sku,qty)
select s.value, q.value
from s join
q
on s.pos = q.pos;
The following CTEs would probably work without those assumptions -- but because the ordering is not stable, the code is not guaranteed to work:
with s as (
select value,
row_number() over (order by charindex(value, #sku)) as pos
from dbo.fn_Split(#sku, ',')
),
q as (
select value,
row_number() over (order by charindex(value, #qty)) as pos
from dbo.fn_Split(#qty, ',')
)
The alternative solutions don't use fn_split(). They would use recursive CTEs or XML.

How To Check MAX value With a Pattern

For example,
I have output like this :-
ID
---
AB1
AB2
AB3
AB4
BD6
If I use MAX(ID), I will get 'BD6' But I want to check MAX Value For Pattern AB
How can I get that?
Simply filter the Data with ID field and then use Max():
EDIT: If ID contains number with more than 1 digits:
SELECT TOP 1 *
FROM
[Table] AS A
WHERE
RIGHT(ID, LEN(ID) - 2) = (SELECT
MAX(Cast(RIGHT(ID, LEN(ID) - 2) AS Int)) FROM [Table] WHERE ID LIKE 'AB%')
AND
ID LIKE 'AB%'
Try This. It will display all max ID for every String .
select CONCAT(ID,id1) as ID from
(
select left(id, patindex('%[^0-9]%', id) + 1) ID , max(cast(substring(id, PatIndex('%[0-9]%', id),len(id)) as numeric)) id1
from #Table
group by left(id, patindex('%[^0-9]%', id) + 1)
)a
For Specific ID value like 'AB' put value into where clause .
select CONCAT(ID,id1) as ID from
(
select left(id, patindex('%[^0-9]%', id) + 1) ID , max(cast(substring(id, PatIndex('%[0-9]%', id),len(id)) as numeric)) id1
from #Table
group by left(id, patindex('%[^0-9]%', id) + 1)
)a
where ID like '%ab%'
OutPut :
outpur for AB111
Check also live demo here.
Try it,
DECLARE #TABLE TABLE(ID VARCHAR(MAX))
INSERT INTO #TABLE (ID)
VALUES('AB1'),('AB2'),('AB3'),('AB4'),('AB11'),('AB111'),('XY112')
DECLARE #Prefix VARCHAR (10) = 'AB'
SELECT #Prefix + CAST(MAX(CAST(SUBSTRING(ID, (LEN(#Prefix) + 1),
(LEN(ID) - 2)) AS INT)) AS VARCHAR) AS ID FROM #TABLE WHERE ID LIKE
#Prefix +'%'
Try this :
SELECT 'AB' + CONVERT(NVARCHAR(10),MAX(CONVERT(INT, Nums.Numbers)))
FROM (SELECT Substring(ID, 3, 10) as Numbers
FROM #Tab tab
WHERE tab.ID LIKE 'AB%') as Nums
You can see this here => http://rextester.com/MAHKWE99983
Hope this helps!!!
You can get by this query.
create table temp
(
id varchar(10)
);
insert into temp values
('AB111'),
('AB1'),
('AB2'),
('AB3'),
('AB4'),
('BD6'),
('AB111')
;
declare #Pattern varchar(5)
set #Pattern='AB'
select distinct(Id) from temp where Id = #Pattern+convert(varchar(10),(
select MAX(Id) as Maximum from (
SELECT convert(integer,REPLACE( Id,#Pattern,'')) as Id FROM temp
where id like 'AB%'
)as test ))
with tmp as (
select 'AB1' id union all
select 'AB2' id union all
select 'AB3' id union all
select 'AB4' id union all
select 'AB111' id union all
select 'BD6' id
)
select top 1 * from tmp f1
where f1.ID LIKE 'AB%' and cast(SUBSTRING(f1.ID, 3, LEN(ID) -2) as integer) in
(
select max(cast(SUBSTRING(f2.ID, 3, LEN(ID) -2) as integer)) from tmp f2
WHERE f2.ID LIKE 'AB%'
)
SELECT MAX(ID) FROM #Tbl
GROUP BY LEFT(col_name,2)