Tags
Complex SQL Challenges, complex sql statement(puzzle), Complex TSQL Challenge, Divide rows into two columns, find records not ending with s, find records not ending with s puzzle, Interesting Interview Questions, Interview Puzzles in SQL Server, Interview Qs.SQL SERVER Questions, Interview questions on Joins, Interview Questions on SQL, Interview SQL Puzzles, InterviewQuestions, InterviewQuestions for SQL, Joins, Joins Interview questions, Joins Puzzle, Khowal, last non null puzzle, Learn complex SQL, Learn SQL, Learn T-SQL, Objective Puzzle, Pawan, Pawan Khowal, Pawan Kumar, Pawan Kumar Khowal, PL/SQL Challenges, Prev Value puzzle, Previous value puzzle, Puzzle SQL, puzzle sql developer, Puzzle SQl Server, Puzzles, PUzzles in SQL SERVER, Queries for SQL Interview, Records not ending with a character Puzzle, Records not ending with s Puzzle, SELECT Puzzle, SQL, SQL 2012, SQL 2014, SQL 2014 Interview Questions, SQL Challenge, SQL Challenges, SQL Interview Questions, SQL Joins, SQL pl/sql puzzles, SQL puzzle, SQL Puzzles, SQL Queries, SQL Quiz, SQL Server Database, SQL server filter index with LIKE and RIGHT function?, SQL Server Interview Puzzle, SQL SERVER Interview questions, SQL Server Puzzle, SQL SERVER Puzzles, SQL Skills, SQL Sudoku, SQL Top clause, SQL Trikcy question, sql/database interview for puzzle sql developer, SQLSERVER, T SQL Puzzles, T-SQL Challenge, T-SQL Puzzle, T-SQL Query | [ Replace 6 Consecutive Digits with x from a string Puzzle ], T-SQL Query | [ Replace 6 or more Consecutive Digits with x from a string Puzzle ], T-SQL Query | [ The Complex Week Puzzle ], T-SQL Tricky Puzzles, The Biggest Gap Puzzle, The Gap Puzzle, The Gap Puzzle Puzzle, The Tree Puzzle, TOP Clause, Tough SQL Challenges, Tough SQL Puzzles, Tricky Questions, TSQL, TSQL Challenge, TSQL Challenges, TSQL Interview questions, TSQL Puzzle, TSQL Puzzles, TSQL Queries, Week puzzle, What You Can (and Can't) Do With Filtered Indexes
T-SQL Query | [ Replace 6 or more Consecutive Digits with x from a string Puzzle ]
Yesterday I was going through one of the puzzle asked in SQL Server Central website. The question is not simple 🙂 ; Here you have to replace all integers with continuous 6 or more occurrences with ‘X’. Less than 6 occurrences of integers should not be replaced. All other characters should not be touched. Let’s first go through the sample input and expected output below-
Pictorial presentation of the puzzle.(Pic taken from SQL Server Central website)
Sample Input
InputString |
1234ABC123456XYZ1234567890ADS |
1234 |
123456 |
123456A!@#$% |
9876542345672a345673456734567 |
9876542345672345673456734567 |
a1AAAAAAAAAAAAAAAAAAAAAAA12345 |
AAAAAA |
Expected Output
InputString | ReplacedString |
1234ABC123456XYZ1234567890ADS | 1234ABCXXXXXXXYZXXXXXXXXXXADS |
1234 | 1234 |
123456 | XXXXXX |
123456A!@#$% | XXXXXXA!@#$% |
9876542345672a345673456734567 | XXXXXXXXXXXXXaXXXXXXXXXXXXXXX |
9876542345672345673456734567 | XXXXXXXXXXXXXXXXXXXXXXXXXXXX |
a1AAAAAAAAAAAAAAAAAAAAAAA12345 | a1AAAAAAAAAAAAAAAAAAAAAAA12345 |
AAAAAA | AAAAAA |
Rules/Restrictions
Add your solution(s) in the comments section or send you solution(s) to pawankkmr@gmail.com
Script
Use the below script to generate the source table and fill them up with the sample data.
-- --Create table and insert some data CREATE TABLE DigitsToReplace ( Chrs VARCHAR(1000) ) GO INSERT INTO DigitsToReplace VALUES ('1234ABC123456XYZ1234567890ADS') INSERT INTO DigitsToReplace VALUES ('1234') INSERT INTO DigitsToReplace VALUES ('123456') INSERT INTO DigitsToReplace VALUES ('123456A!@#$%') INSERT INTO DigitsToReplace VALUES ('') INSERT INTO DigitsToReplace VALUES (' ') INSERT INTO DigitsToReplace VALUES ('9876542345672a345673456734567') INSERT INTO DigitsToReplace VALUES ('9876542345672345673456734567') INSERT INTO DigitsToReplace VALUES ('a1AAAAAAAAAAAAAAAAAAAAAAA12345') INSERT INTO DigitsToReplace VALUES ('AAAAAA') --
Update Oct 5 | Solutions # – Pawan Kumar Khowal
-- --Table Valued function CREATE FUNCTION [dbo].[Replace6ContinousDigits] ( @InputString VARCHAR(1000) ) RETURNS @results TABLE ( final VARCHAR(1000) ) AS BEGIN DECLARE @Sttrs AS VARCHAR(1000) = @InputString DECLARE @totals AS INT = 0 DECLARE @Counter AS INT = 1 SET @totals = DATALENGTH(@Sttrs) DECLARE @Chrs TABLE (rnk TinyInt , Chars Char(1) , Digit TinyInt) WHILE (@Counter <= @totals) BEGIN INSERT INTO @Chrs VALUES ( @Counter ,SUBSTRING(@Sttrs,@Counter,1) ,CASE WHEN SUBSTRING(@Sttrs,@Counter,1) LIKE '[0-9]' THEN 1 ELSE @Counter END ) SET @Counter = @Counter + 1 END ;WITH CTE AS ( SELECT *, CASE WHEN Digit = lag(Digit) OVER(ORDER BY rnk) THEN 0 ELSE 1 END cols FROM @Chrs c2 ) ,CTE1 AS ( SELECT * , SUM(cols) OVER (ORDER BY rnk) grouper FROM CTE ) ,CTE2 AS ( SELECT *, COUNT(*) OVER (PARTITION BY grouper) ConsecutiveDigits FROM CTE1 ) ,CTE3 AS ( SELECT chars, ConsecutiveDigits , ROW_NUMBER() OVER (PARTITION BY ConsecutiveDigits ORDER BY (SELECT NULL)) nkr FROM CTE2 c WHERE c.ConsecutiveDigits &gt; 5 ) UPDATE c SET c.Chars = 'X' FROM CTE3 c DECLARE @final AS VARCHAR(1000) = '' SELECT @final = @final + Chars FROM @Chrs INSERT @results (final) SELECT @final RETURN; END ---Usage SELECT Chrs InputString, final ReplacedString FROM DigitsToReplace CROSS APPLY ( SELECT final FROM [dbo].[Replace6ContinousDigits] (Chrs) ) A -- |
Thanks Guys ! Add a comment if you have any other solution in mind. We all need to learn. Keep Learning 🙂
Http://MSBISkills.com
Pawan Kumar Khowal
Pingback: SQL Server String Puzzles & Tricks | Improving my SQL BI Skills
Pingback: SQL Puzzle | The Sum of maximum consecutive values puzzle (1) | Improving my SQL BI Skills
I wrote the following not realizing that writing separate table valued functions was allowed.
;with dtr as (
select row_number() over(order by [chrs]) as row_num, [Chrs], len([Chrs]) as lenChrs
from DigitsToReplace
where patindex(‘%[0-9][0-9][0-9][0-9][0-9][0-9]%’, [Chrs]) >= 1
), p as (
select row_num, [Chrs], substring([Chrs], 1, 1) as c, 1 as pos, isnumeric(substring([Chrs], 1, 1)) as is_number
from dtr
union all
select p.row_num, p.[Chrs], substring(p.[Chrs], pos + 1, 1) as c, pos + 1 as pos, isnumeric(substring(p.[Chrs], pos + 1, 1))
from p
join dtr on p.row_num = dtr.row_num
where pos = 6
), d1 as (
select row_num, [Chrs], row_number() over(partition by row_num order by [Chrs], start_pos) as row_num2, [Chrs] as [inputStr], start_pos, span, replicate(‘X’, span) as sub, stuff([Chrs], start_pos, span, replicate(‘X’, span)) as [outputStr]
from rs
), rd1 as (
select row_num, row_num2, [inputStr], [outputStr]
from d1
where row_num2 = 1
union all
select d1.row_num, d1.row_num2, rd1.[inputStr], stuff(rd1.[outputStr], d1.start_pos, d1.span, d1.sub)
from rd1
join d1 on (rd1.row_num2 + 1) = d1.row_num2 and rd1.row_num = d1.row_num
)
select
dtr.[Chrs] as [InputString],
rd1.[OutputStr] as [ReplacedString]
from dtr
join rd1 on dtr.[Chrs] = rd1.[inputStr]
where
rd1.row_num2 = (select max(row_num2) from rd1 as rd12 where rd12.row_num = rd1.row_num)
union all
select [Chrs], [Chrs]
from DigitsToReplace
where patindex(‘%[0-9][0-9][0-9][0-9][0-9][0-9]%’, [Chrs]) = 0
LikeLiked by 1 person
Try this one instead:
;with dtr as (
select row_number() over(order by [chrs]) as row_num, [Chrs], len([Chrs]) as lenChrs
from DigitsToReplace
where patindex(‘%[0-9][0-9][0-9][0-9][0-9][0-9]%’, [Chrs]) >= 1
), p as (
select row_num, [Chrs], substring([Chrs], 1, 1) as c, 1 as pos, isnumeric(substring([Chrs], 1, 1)) as is_number
from dtr
union all
select p.row_num, p.[Chrs], substring(p.[Chrs], pos + 1, 1) as c, pos + 1 as pos, isnumeric(substring(p.[Chrs], pos + 1, 1))
from p
join dtr on p.row_num = dtr.row_num
where pos = 6
), d1 as (
select row_num, [Chrs], row_number() over(partition by row_num order by [Chrs], start_pos) as row_num2, [Chrs] as [inputStr], start_pos, span, replicate(‘X’, span) as sub, stuff([Chrs], start_pos, span, replicate(‘X’, span)) as [outputStr]
from rs
), rd1 as (
select row_num, row_num2, [inputStr], [outputStr]
from d1
where row_num2 = 1
union all
select d1.row_num, d1.row_num2, rd1.[inputStr], stuff(rd1.[outputStr], d1.start_pos, d1.span, d1.sub)
from rd1
join d1 on (rd1.row_num2 + 1) = d1.row_num2 and rd1.row_num = d1.row_num
)
select
dtr.[Chrs] as [InputString],
rd1.[OutputStr] as [ReplacedString]
from dtr
join rd1 on dtr.[Chrs] = rd1.[inputStr]
where
rd1.row_num2 = (select max(row_num2) from rd1 as rd12 where rd12.row_num = rd1.row_num)
union all
select [Chrs], [Chrs]
from DigitsToReplace
where patindex(‘%[0-9][0-9][0-9][0-9][0-9][0-9]%’, [Chrs]) = 0
LikeLiked by 1 person
Excellent sir !!
LikeLike
Something is happening with copy/paste. Disregard these both.Filters are getting changed, and at least 3 cte’s are missing.
LikeLiked by 1 person