SQL function - Split a number into part count - sql

I want to split a number into parts(buckets).
For example when I split a number 13 by 4, expected output is 4 bucket (4,4,4,1)
13 split by 4 parts -> 4 (Expected output)
For example when I split a number 11 by 4, expected output is 3 bucket (4,4,3)
11 split by 4 parts -> 3 (Expected output)
For example when I split a number 3 by 4, expected output is 1 bucket
3 split by 4 parts -> 1 (Expected output)
How do I do this in SQL function

You Can use next Code for retrieving the buckets and the count:-
Declare
#InputNumber int,
#SplitBy int,
#Count int,
#Buckets VARCHAR(1000)
Set #InputNumber = 14
Set #SplitBy = 4
Set #Count = 0
While #InputNumber > #SplitBy
Begin
Set #Buckets = Convert(Varchar(10),#SplitBy) + ',' + isNULL( #Buckets,'')
Set #InputNumber = #InputNumber - #SplitBy
Set #Count = #Count + 1
End
Select #Buckets + Convert(Varchar(10),#InputNumber% #SplitBy) as Buckets , #Count + 1 as Count
Output:-
Buckets Count
4,4,4,2 4

You can try this way:
DECLARE #Number INT = 13, #Devided INT = 4, #Count INT = 0
WHILE (#Number >= #Devided)
BEGIN
set #Count = #Count + 1;
set #Number = #Number - #Devided
print #Devided
END
IF(#Number < #Devided)
BEGIN
Set #Count = #Count + 1;
print #Number
END
SELECT #Count
If you just want to count, you can try this way, demo on db<>fiddle
DECLARE #Number INT = 13, #Devided INT = 4, #Count INT
SET #Count = (#Number / #Devided)
IF(#Number % #Devided <> 0)
BEGIN
Set #Count = #Count + 1;
END
SELECT #Count

Hard to tell what exactly you're looking for, but using SQL functions only, here is one way. Try plugging in different numbers.
declare #num integer;
set #num=11;
select #num, concat(replicate('4,',floor(#num/4)),#num%4), floor(#num/4)+1;

Related

SQL: how to check palindrome of a string without using reverse function?

I'm using SQL Server and I want to check whether the given string is a palindrome or not - but without using the reverse function.
There are multiple ways to achieve this. One of them is to check first and last character, slicing them if they're equal and continuing the process in a loop.
DECLARE #string NVARCHAR(100)
DECLARE #counter INT
SET #string = 'Your string'
SET #counter = LEN(#string)/2
WHILE (#counter > 0)
BEGIN
IF LEFT(#string,1) = RIGHT(#string,1)
BEGIN
SET #string = SUBSTRING(#string,2,len(#string)-2)
SET #counter = #counter - 1
END
ELSE
BEGIN
PRINT ('Given string is not a Palindrome')
BREAK
END
END
IF(#counter = 0)
PRINT ('Given string is a Palindrome')
A select without loops
DECLARE #Test VARCHAR(100)
SELECT #Test = 'qwerewq'
SELECT CASE WHEN LEFT(#Test, LEN(#Test)/2) =
(
SELECT '' + SUBSTRING(RIGHT(#Test, LEN(#Test)/2), number, 1)
FROM master.dbo.spt_values
WHERE type='P' AND number BETWEEN 1 AND LEN(#Test)/2
ORDER BY number DESC
FOR XML PATH('')
)
THEN 1
ELSE 0
END
Here's an example using LEFT and RIGHT. I use the #count variable to change position, then grab the left-most and right-most char:
DECLARE #mystring varchar(100) = 'redivider'
DECLARE #count int = 1
WHILE (#count < LEN(#mystring) / 2) AND #count <> 0
BEGIN
IF (RIGHT(LEFT(#mystring, #count), 1) <> LEFT(RIGHT(#mystring, #count), 1))
SET #count = 0
ELSE SET #count += 1
END
SELECT CASE WHEN #count = 0
THEN 'Not a Palindrome'
ELSE 'Palindrome'
END [Result]

SQL - Combine results in whileloop

i would like to get a single results using this code
DECLARE
#count INT = 1,
#cutoff DATETIME = '12/31/2015'
while #count < 30
begin
select COUNT(Accnumber) from table
where DATEDIFF(day,TranDateTime,#cutoff) <= 0
SET #count = #count + 1
end
EDIT: i already fix it. what i did was i add a variable for the table and insert into it and display the result. sorry for bad english :D
so,
DECLARE
#count INT = 1,
#cutoff DATETIME = '12/31/2015',
*#tbl table(result int)*
while #count < 30
begin
*insert into #tbl*
select COUNT(Accnumber) from table
where DATEDIFF(day,TranDateTime,#cutoff) <= 0
SET #count = #count + 1
end
*select * from #tbl*
im new here i don't know how to format answers correctly. again thanks for the response.

In SQL server, how could I select top #num percent in a loop

Here is what I am trying to do:
run a loop 3 times; each time i randomly select top 5%, 10%, 15% from the table, respectively. However, in the output table, the column 'Ratio' is 5 for every row and the column name is not 'Ratio. The first column in the output table should show the ratio that is applied, i.e., including 5%, 10%, 15%. Thanks!
Below is my code:
DECLARE #intFlag INT
DECLARE #endFlag INT
DECLARE #num INT
DECLARE #totalScen INT
SET #intFlag = 1
SET #endFlag=5
SET #num =5
SET #totalScen =15
WHILE (#num <= #totalScen)
BEGIN
WHILE (#intFlag <= #endFlag)
BEGIN
WITH cte AS (select t1.gender, t1.age_group
from
(
select * from mytable1
where caseid not in
(
select top (#num) percent caseid from mytable1
order by newid()
)
) t1
)
INSERT INTO newTable
SELECT #num as Ratio, gender, age_group
FROM cte
SET #intFlag = #intFlag + 1
END
SET #num=#num+5
END
GO
I'm assuming based on your question that you want the inner loop to run 5x for each of your ratio values 5,10,15. If that's the case you need to move the variables used in the inner loop to the inner loop:
DECLARE #num INT = 5
,#totalScen INT = 15
WHILE (#num <= #totalScen)
BEGIN
DECLARE #intFlag INT = 1
,#endFlag INT = 5
WHILE (#intFlag <= #endFlag)
BEGIN
WITH cte AS (select t1.gender, t1.age_group
from (select *
from mytable1
where caseid not IN (select top (#num) percent caseid
from mytable1
order by newid()
)
) t1
)
INSERT INTO newTable
SELECT #num as Ratio, gender, age_group
FROM cte
SET #intFlag = #intFlag + 1
END
SET #num=#num+5
END
GO
Easy way to test behavior is by printing variables:
DECLARE #num INT = 5
,#totalScen INT = 15
WHILE (#num <= #totalScen)
BEGIN
DECLARE #intFlag INT = 1
,#endFlag INT = 5
WHILE (#intFlag <= #endFlag)
BEGIN
PRINT #num
PRINT #intflag
SET #intFlag = #intFlag + 1
END
SET #num=#num+5
END
GO
Your problem comes from value for inner loop never resetting it self. You have to move
SET #intFlag = 1
SET #endFlag = 5
Inside your outer loop. Like so.
DECLARE #intFlag INT
,#endFlag INT
,#num INT
,#totalScen INT
SET #num = 5
SET #totalScen = 15
WHILE ( #num <= #totalScen )
BEGIN
SET #intFlag = 1
SET #endFlag = 5
WHILE ( #intFlag <= #endFlag )
BEGIN
PRINT '#intFlag:' + CONVERT(VARCHAR(2), #intFlag)
SET #intFlag = #intFlag + 1
END
PRINT '#num2:' + CONVERT(VARCHAR(2), #num)
SET #num = #num + 5
END
Always best to use PRINT to see what values your variables are instead of assuming that it is behaving correctly.

Assign a unique number in a range randomly

I need to assign a list of employees a unique number from 1 to 1000 (or however many employees there are). The numbers can't repeat and need to be in a random order against the employee list. The numbers also need to be regenerated each week so the employee is assigned a new number.
I have tried to use the following, however the script is slow and it returns the same number for all employees.
DECLARE #Random INT;
DECLARE #Upper INT;
DECLARE #Lower INT
SET #Lower = 1
SET #Upper = 1000
SELECT #Random = ROUND(((#Upper - #Lower -1) * RAND() + #Lower), 0)
select personnum, firstnm, lastnm, (SELECT #Random)
from person
Can anyone shed any light on how to do this?
Thanks
Works on mssql server 2005+
select personnum, firstnm, lastnm, row_number() over (order by newid()) randomnumber
from person
Create a function for it. Here is one we use:
ALTER FUNCTION [dbo].[fn_GenerateUniqueNumber]()
RETURNS char(10)
AS
BEGIN
--DECLARE VARIABLES
DECLARE #RandomNumber VARCHAR(10)
DECLARE #I SMALLINT
DECLARE #RandNumber FLOAT
DECLARE #Position TINYINT
DECLARE #ExtractedCharacter VARCHAR(1)
DECLARE #ValidCharacters VARCHAR(255)
DECLARE #VCLength INT
DECLARE #Length INT
--SET VARIABLES VALUE
SET #ValidCharacters = '0123456789'
SET #VCLength = LEN(#ValidCharacters)
SET #ExtractedCharacter = ''
SET #RandNumber = 0
SET #Position = 0
SET #RandomNumber = ''
SET #Length = 10
SET #I = 1
WHILE #I < ( #Length + 1 )
BEGIN
SET #RandNumber = (SELECT RandNumber FROM [RandNumberView])
SET #Position = CONVERT(TINYINT, ( ( #VCLength - 1 ) * #RandNumber + 1 ))
SELECT #ExtractedCharacter = SUBSTRING(#ValidCharacters, #Position, 1)
SET #I = #I + 1
SET #RandomNumber = #RandomNumber + #ExtractedCharacter
END
RETURN #RandomNumber
END
To use it do something like this:
SELECT personnum, firstnm, lastnm,dbo.fn_GenerateUniqueNumber()
FROM person
You can modify the parameters and allowed values to ensure it is the type of number you want.

How to check upper case existence length in a string - Sql Query

How to check upper case existence length in a string using Sql Query?
For Eg:
1.KKart - from this string the result should be 2, because it has 2 upper case letters.
2.WPOaaa - from this string the result should be 3, because it has 3 upper case letters.
Thanks in advance
There is no built-in T-SQL function for that.
You can use a user-defined function like this one:
CREATE FUNCTION CountUpperCase
(
#input nvarchar(50)
)
RETURNS int
AS
BEGIN
declare #len int
declare #i int
declare #count int
declare #ascii int
set #len = len(#input)
set #i = 1
set #count = 0
while #i <= #len
begin
set #ascii = ascii(substring(#input, #i, 1))
if #ascii >= 65 and #ascii <= 90
begin
set #count = #count +1
end
set #i = #i + 1
end
return #count
END
Usage (with the examples from your question):
select dbo.CountUpperCase('KKart') returns 2.
select dbo.CountUpperCase('WPOaaa') returns 3.
How about something like this :
SELECT len(replace(my_string_field,'abcdefghijklmnopqrstuvwxyz','')) as 'UpperLen'
FROM my_table
The principle is simply to replace all lower case char by nothing and counts the remaining.