I have a table p
id_people age
1 22
2 ---> (empty)
3 (10,20)
I want to get result like this
id_people age
1 22
3 10
3 20
I have tried this
select t.id_people,
STRTOK(t.age,',',1) AS COL_1,STRTOK(t.age,',',2) AS COL_2 from
(select id_people,age from p where LENGTH(age) >0 ) t
First of all , it works but i still have the brackets. how can i delete brackets ? Second question : It works fine because i know i have only one comma in a row, if i didn't know the number of comma in a row for column age, i wouldn't be able to handle by this way.
How can I use a kind of loop for a situation like that?
Example :
id_people age
1 (17,18,19,20,21,22,23,24,25,....)
2 (30,31,32)
3 --> (empty)
Thank you
Besides STRTOK there's also STRTOK_SPLIT_TO_TABLE :-)
The syntax is a bit unusual:
WITH cte (id_people, age) AS
(
SELECT id_people, age FROM dropme
)
SELECT *
FROM TABLE
( STRTOK_SPLIT_TO_TABLE( cte.id_people , cte.age, '(),')
RETURNS ( id_people INT , TokenNum INT , Token VARCHAR (10) CHARACTER SET UNICODE )
) dt
Related
I have a table in a database and one of the columns of the table is of the format AAA-BBBBBBB-CCCCCCC(in the table below column Id) where A, B and C are all numbers (0-9). I want to write a SELECT query such that for this column I only want the values in the format BBBBBBB-CCCCCCC. I am new to SQL so not sure how to do this. I tried using SPLIT_PART on - but not sure how to join the second and third parts.
Table -
Id
Name
Age
123-4567890-1234567
First Name
199
456-7890123-4567890
Hulkamania
200
So when the query is written the output should be like
Output
4567890-1234567
7890123-4567890
As mentioned in the request comments, you should not store a combined number, when you are interested in its parts. Store the parts in separate columns instead.
However, as the format is fixed 'AAA-BBBBBBB-CCCCCCC', it is very easy to get the substring you are interested in. Just take the string from the fifth position on:
select substr(col, 5) from mytable;
You can select the right part of a column starting at the 4th character
SELECT RIGHT(Id, LEN(Id)-4) AS TrimmedId;
Another option using regexp_substr
with x ( c1,c2,c3 ) as
(
select '123-4567890-1234567', 'First Name' , 199 from dual union all
select '456-7890123-4567890', 'Hulkamania' , 200 from dual
)
select regexp_substr(c1,'[^-]+',1,2)||'-'||regexp_substr(c1,'[^-]+',1,3) as result from x ;
Demo
SQL> with x ( c1,c2,c3 ) as
(
select '123-4567890-1234567', 'First Name' , 199 from dual union all
select '456-7890123-4567890', 'Hulkamania' , 200 from dual
)
select regexp_substr(c1,'[^-]+',1,2)||'-'||regexp_substr(c1,'[^-]+',1,3) as result from x ; 2 3 4 5 6
RESULT
--------------------------------------------------------------------------------
4567890-1234567
7890123-4567890
SQL>
I have to write a select query to get the value from a comma delimited column based on the position. When i say position means every value between comma considered as one position.
Example:
Source table 'alphabets' has one column with value as below
Column1
abc,defg,hi,j,kl,mno,pqr,st,u,v,wx,yz
Now i have to select the 7th position value which is 'pqr' as my output in SQL Server 2012.
I have came up with temporary solution for the consistent length values but need help for selecting the inconsistent length values.
Can anyone help me on this scenario?
Thanks in Advance!!
you can split the string with comma:
;WITH alphabets(s)AS(
SELECT 'abc,defg,hi,j,kl,mno,pqr,st,u,v,wx,yz'
)
SELECT l.* FROM alphabets AS a
CROSS APPLY(VALUES(CONVERT(XML,'<n>'+REPLACE(a.s,',','</n><n>')+'</n>')))c(x)
CROSS APPLY(SELECT ROW_NUMBER()OVER(ORDER BY GETDATE()) AS Pos,x.n.value('.','varchar(100)') AS ch FROM c.x.nodes('n')x(n)) l
Pos ch
1 abc
2 defg
3 hi
4 j
5 kl
6 mno
7 pqr
8 st
9 u
10 v
11 wx
12 yz
I tried the below sample.Which give the postion of the 7th row.Hope it resolves the problem.
create table #alphabets
(
val varchar(100)
)
insert into #alphabets
values
('abc'),
('defg'),
('hi'),
('j'),
('kl'),
('mno'),
('c'),
('st'),
('u'),
('v'),
('wx'),
('yz')
SELECT ROW_NUMBER() OVER(ORDER BY val) as ronumber,val into #temp1 From #alphabets
select * from #temp1 where ronumber = 7
I want to find names with repetitive char in them for example :
ana
asdbbiop
a1for1
#mail#ban
I found a similar question here but they were consecutive ones.
I know 2 way :
1.using helping table and join
2.a very long "where like" statement
is there any way to do it with regex?
This codes will helps you find the repetitive characters find in the word and count of characters
Sample Data
DECLARE #Table TABLE (ID INT,String nvarchar(100))
INSERT INTO #Table
SELECT 1,'ana' UNION ALL
SELECT 2,'asdbbiop' UNION ALL
SELECT 3,'a1for1' UNION ALL
SELECT 4,'#mail#ban'
SELECT * FROM #Table
Using Recursive Cte we get the expected Result
;With cte
AS
(
SELECT ID, String
,CAST(LEFT(String,1)AS VARCHAR(10)) AS Letter
,RIGHT(String,LEN(String)-1) AS Remainder
FROM #Table
WHERE LEN(String)>1
UNION ALL
SELECT ID, String
,CAST(LEFT(Remainder,1)AS VARCHAR(10)) AS Letter
,RIGHT(Remainder,LEN(Remainder)-1) AS Remainder
FROM cte
WHERE LEn(Remainder)>0
)
SELECT ID,
String,
letter,
Ascii(letter) AS CharCode,
Count(letter) AS CountOfLetter
FROM cte
GROUP BY ID,
String,
letter,
Ascii(letter)
HAVING COUNT(letter)>1
Result
ID String letter CharCode CountOfLetter
---------------------------------------------
1 ana a 97 2
2 asdbbiop b 98 2
3 a1for1 1 49 2
4 #mail#ban # 64 2
4 #mail#ban a 97 2
I am using SQL Server 2008 R2 and have a table like this:
ID Record
1 IA12345
2 IA33333
3 IA33333
4 IA44444
5 MO12345
I am trying to put together some SQL to return the two rows that contain IA12345 and MO12345. So, I need to match on the partial string of the column "Record". What is complicating my SQL is that I don't want to return matches like IA33333 and IA33333. Clear as mud?
I am getting twisted up in substrings, group by, count and the like!
SELECT ID, Record FROM Table WHERE Record LIKE '%12345'
Select *
from MyTable
where Record like '%12345%'
This will find repeating and/or runs. For example 333 or 123 or 321
Think of it as Rummy 500
Declare #YourTable table (ID int,Record varchar(25))
Insert Into #YourTable values
( 1,'IA12345'),
( 2,'IA33333'),
( 3,'IA33333'),
( 4,'IA44444'),
( 5,'MO12345'),
( 6,'M785256') -- Will be excluded because there is no pattern
Declare #Num table (Num int);Insert Into #Num values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)
Select Distinct A.*
From #YourTable A
Join (
Select Patt=replicate(Num,3) from #Num
Union All
Select Patt=right('000'+cast((Num*100+Num*10+Num)+12 as varchar(5)),3) from #Num where Num<8
Union All
Select Patt=reverse(right('000'+cast((Num*100+Num*10+Num)+12 as varchar(5)),3)) from #Num where Num<8
) B on CharIndex(Patt,Record)>0
Returns
ID Record
1 IA12345
2 IA33333
3 IA33333
4 IA44444
5 MO12345
EDIT
I should add that runs of 3 is too small, it is a small matter tweak the sub-queries so 333 becomes 3333 and 123 becomes 1234
I have a table with one column containing different integers.
For each integer in the table I would like to duplicate it as the number of digits -
For example:
12345 (5 digits):
1. 12345
2. 12345
3. 12345
4. 12345
5. 12345
I thought doing it using with recursion t (...) as () but I didn't manage, since I don't really understand how it works and what is happening "behind the scenes.
I don't want to use insert because I want it to be scalable and automatic for as many integers as needed in a table.
Any thoughts and an explanation would be great.
The easiest way is to join to a table with numbers from 1 to n in it.
SELECT n, x
FROM yourtable
JOIN
(
SELECT day_of_calendar AS n
FROM sys_calendar.CALENDAR
WHERE n BETWEEN 1 AND 12 -- maximum number of digits
) AS dt
ON n <= CHAR_LENGTH(TRIM(ABS(x)))
In my example I abused TD's builtin calendar, but that's not a good choice, as the optimizer doesn't know how many rows will be returned and as the plan must be a Product Join it might decide to do something stupid. So better use a number table...
Create a numbers table that will contain the integers from 1 to the maximum number of digits that the numbers in your table will have (I went with 6):
create table numbers(num int)
insert numbers
select 1 union select 2 union select 3 union select 4 union select 5 union select 6
You already have your table (but here's what I was using to test):
create table your_table(num int)
insert your_table
select 12345 union select 678
Here's the query to get your results:
select ROW_NUMBER() over(partition by b.num order by b.num) row_num, b.num, LEN(cast(b.num as char)) num_digits
into #temp
from your_table b
cross join numbers n
select t.num
from #temp t
where t.row_num <= t.num_digits
I found a nice way to perform this action. Here goes:
with recursive t (num,num_as_char,char_n)
as
(
select num
,cast (num as varchar (100)) as num_as_char
,substr (num_as_char,1,1)
from numbers
union all
select num
,substr (t.num_as_char,2) as num_as_char2
,substr (num_as_char2,1,1)
from t
where char_length (num_as_char2) > 0
)
select *
from t
order by num,char_length (num_as_char) desc