I have a problem with dividing in SQL Server.
I am dividing 100/6.00. And it gives me 16.67, 16.67, 16.67, 16.67, 16.67, 16.67
Which is 100.02 at the end.
Is there a way to divide 100/6.00 and get 16.66, 16.66, 16.67, 16.67, 16.67, 16.67 as a result?
I don't look for solution like iif(final sum>100) then . Is there other way to do this?
Thanks
If you want exact division, then the general answer here is to use an exact type, such as NUMERIC or DECIMAL. Consider:
WITH yourTable AS (
SELECT CAST(100.0 AS NUMERIC(10, 2)) AS num
)
SELECT num / 6 AS output -- output is 16.666666
FROM yourTable;
...test
declare #amount decimal(9,4) = 100;
declare #den decimal(9,4) = 6.00;
declare #dp tinyint = 2; --decimal points for rounding
select val as colid,
round(#amount/ceiling(#den), #dp,1) +
case when val <= power(10, #dp) * ((#amount- ceiling(#den) * round(#amount/ceiling(#den), #dp,1))%ceiling(#den)) then power(10.0000000000, -#dp)
else 0.00000 end
from (values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) as v(val) --max denominator:10
where val <= ceiling(#den);
Can this somehow help you?
DECLARE #counter numeric(5,2)
DECLARE #row int
DECLARE #number numeric(2,1)
SET #counter= 100
SET #number = 6.0
SET #row = 1
while #counter != 0
BEGIN
select #counter,#number,#row,#counter/#number
set #counter = #counter - #counter/#number
set #number = #number - 1
set #row = #row + 1
END
Related
This query converts dynamic int to binary, but I want to split into rows.
declare #value int
set #value = 96
declare #result varchar(32)
set #result = ''
while 1 = 1
begin
select
#result = convert(char(1), #value % 2) + ',' +#result,
#value = convert(int, #value / 2)
if #value = 0 break
end
select substring(#result, 1, len(#result)-1) as result
Please help me to find a solution.
This is the result of my query.
1,1,0,0,0,0,0
My question is: how can I split this result into rows from right to left?
My result will need to be this (I'm trying to insert into a #table):
0
0
0
0
0
1
1
Thanks
Using a WHILE seems like a really bad idea. If you want to achieve what you have this would be a far faster solution:
DECLARE #I int = 96
SELECT CONVERT(bit,#i & V.b)
FROM (VALUES(1),(2),(4),(8),(16),(32),(64)) V(b)
ORDER BY V.b;
I'd like to add serial number based on every 5 records. There are some columns in my table: flag, seq_no and page_no.
If seq_no is equal to 1,2,3,4,5, page_no would be updated and set to 1.
If seq_no is equal to 6,7,8,9,10, page_no would be updated and set to 2, and so on.
I'm using SQL Server 2000.
My code as below but wrong:
--set page_no
Declare #page_number int
Declare #i int, #k int
set #i = 1
set #k = 1
while #k <= 5
begin
update dbo.test
set #page_number = page_no = case
when #k = 5 then (#i + 1)
else #i
end
where flag = 'right'
set #k = #k + 1
end
How can I do so? Please help me and so much thanks.
You could try something like:
UPDATE dbo.test
SET page_no = ((seq_no - 1) / 5) + 1
This will set the value of page_no to the value you want based on the value of seq_no.
i'm pretty new to SQL and stored procedures and i'm a bit stuck - so any help would be appreciated
how do i loop through each row and assign it the random value i'm generating?
Here is my Storedproc:
CREATE PROCEDURE StoredProc8
AS
BEGIN
DECLARE #total INT
DECLARE #Count INT = 0
DECLARE #Random INT = 0
SELECT #total = COUNT(CustomerID) FROM Customers
WHILE(#Count<= #total)
BEGIN
SELECT #Random = 2 * RAND()
EXEC ('update Customers set col1= ' + #Random )
SELECT #Count = #Count+1
END
END
If you simple need to assign 0 or 1 randomly - you can use RAND() with random seed:
UPDATE Customers SET COL1 = RAND(CHECKSUM(NEWID()))*2
Demo: http://sqlfiddle.com/#!3/31699/9
I found a few threads on this using the search feature, but nothing for a purely T-SQL solution.
the need - A system is storing a weekly schedule as 0's and 1's in a string format to represent a week. 1 means yes, 0 means no....so 1100111 means sunday yes (first one), Monday yes (second 1), Tuesday no (the 0)...etc.
Short question - How do I go from an ascii char such as '>' to it's hex code '3E' and ultimately to it's binary '00111110' representation?
Long question - I'm extracting from a flat file system that stores a table as:
ID int,
priority_1 varchar(2)
...
It actually goes to priroity_128 (silly flat file), but I'm only interested in 1-7 and the logic for one should be easily reused for the others. I unfortunately have no control over this part of the extract. The values I get look like:
1 >
2 (edit, I actually put a symbol here that I receive from the system but the forum doesn't like.)
3 |
4 Y
I get the feeling these are appearing as their ascii chars because of the conversion as I extract.
select convert(varbinary,'>',2)
This returns 0x3E. The 0x part can be ignored... 3 in binary is 0011 and E is 1110...3E = 00111110. Trim the first 0 and it leaves the 7 bit code that I'm looking for. Unfortunately I have no idea how to express this logic here in T-SQL. Any ideas? I'm thinking as a function would be easiest to use...something like:
select id, binaryversionof(priority_1)
Here's a UDF that will convert from base-10 to any other base, including base-2...
Here's how you can use it:
SELECT YourDatabase.dbo.udf_ConvertFromBase10(convert(varbinary, '>', 2), 2)
Here's what it returns:
111110
And here's the function definition:
CREATE FUNCTION [dbo].[udf_ConvertFromBase10]
(
#num INT,
#base TINYINT
)
RETURNS VARCHAR(255)
AS
BEGIN
-- Check for a null value.
IF (#num IS NULL)
RETURN NULL
-- Declarations
DECLARE #string VARCHAR(255)
DECLARE #return VARCHAR(255)
DECLARE #finished BIT
DECLARE #div INT
DECLARE #rem INT
DECLARE #char CHAR(1)
-- Initialize
SELECT #string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
SELECT #return = CASE WHEN #num <= 0 THEN '0' ELSE '' END
SELECT #finished = CASE WHEN #num <= 0 THEN 1 ELSE 0 END
SELECT #base = CASE WHEN #base < 2 OR #base IS NULL THEN 2 WHEN #base > 36 THEN 36 ELSE #base END
-- Loop
WHILE #finished = 0
BEGIN
-- Do the math
SELECT #div = #num / #base
SELECT #rem = #num - (#div * #base)
SELECT #char = SUBSTRING(#string, #rem + 1, 1)
SELECT #return = #char + #return
SELECT #num = #div
-- Nothing left?
IF #num = 0 SELECT #finished = 1
END
-- Done
RETURN #return
END
Your solution returns a string of a variable length. Not sure whether it was by design or you simply overlooked that fact.
Anyway, here's my solution, which always returns 7 0s or 1s:
CREATE FUNCTION fnIntTo7Bits (#Value int)
RETURNS varchar(7)
AS BEGIN
DECLARE #Bits varchar(7);
SELECT #Bits = COALESCE(#Bits, '') + CAST(CAST(#Value & number AS bit) AS varchar)
FROM master..spt_values
WHERE type = 'P' AND number IN (1, 2, 4, 8, 16, 32, 64)
ORDER BY number DESC;
RETURN #Bits;
END;
The master..spt_values table is a system table used internally but also accessible to the user. It seems to have been inherited from Sybase so it's a very old tool, which, to my mind, means it won't go too soon.
But if you like, you can use your own number table, which you don't even have to materialise, like this:
...
SELECT #Bits = COALESCE(#Bits, '') + CAST(CAST(#Value & number AS bit) AS varchar)
FROM (
SELECT 1 UNION ALL SELECT 2 UNION ALL
SELECT 4 UNION ALL SELECT 8 UNION ALL
SELECT 16 UNION ALL SELECT 32 UNION ALL SELECT 64
) s (number)
ORDER BY number DESC;
...
Answering my own question...though curious if anyone has something more elegant. I found this unsourced function using google:
CREATE FUNCTION udf_bin_me (#IncomingNumber int)
RETURNS varchar(200)
as
BEGIN
DECLARE #BinNumber VARCHAR(200)
SET #BinNumber = ''
WHILE #IncomingNumber <> 0
BEGIN
SET #BinNumber = SUBSTRING('0123456789', (#IncomingNumber % 2) + 1, 1) + #BinNumber
SET #IncomingNumber = #IncomingNumber / 2
END
RETURN #BinNumber
END
Then use the Ascii function to get the char to it's ascii decimal value:
select dbo.udf_bin_me(ascii('>'))
Seems to be a bit of a run around, but I can work from that. Better solution anyone?
I just whipped this up, it maybe buggy... but it works:
DECLARE #value INT, #binary VARCHAR(10)
SELECT #value = ASCII('m'), #binary = ''
;WITH [BINARY] ([Location], [x], [BIT])
AS
(
-- Base case
SELECT 64, #value, #value % 2
UNION ALL
-- Recursive
SELECT [BINARY].[Location] / 2, [BINARY].[x] / 2, ([BINARY].[x] / 2) % 2
FROM [BINARY]
WHERE [BINARY].[Location] >= 2
)
SELECT #binary = CAST([BIT] AS CHAR(1)) + #binary FROM [BINARY]
SELECT #binary
suppose I have a number 62. This is composed of 2 digits
How can add 2 digit together divide by 10 and if result = something like 6.2 just take reminder
declare #Number int,#Result int
set #Number =62
if len(#Number) > 1
set #Result=????=--Add 6 and 2 =8
set #result=#result % 10 --Mod operator
print #result
-- the result should be 2 in this case
what Am I doing wrong?
Thanks a lot
set #tens = floor(#Number / 10);
set #ones = #number - #tens;
set #Result = #tens + #ones;
Or use left and right to access substrings.
I have no way to try it:
DECLARE #Number VARCHAR(2)
SET #Number = '62'
declare #firstNum INT, #secondNum INT
SET #firstNum = CAST(SUBSTRING(#Number, 1, 1) AS INT)
SET #secondNum = CAST(SUBSTRING(#Number, 2, 1) AS INT)
DECLARE #Result int
SET #Result = (#firstNum + #secondNum) % 10
I think #Number % 10is what you are looking for. It returns the last digit of any number. 62 -> 2, 97 -> 7, etc...
Update:
I may have misunderstood the question. Maybe you want 10 % ((#Number / 10) + #Number) instead.
(#Number / 10) + #Number is the sum of the digits of a two-digit number.
If the number is always two digits, then I would use LEFT(#Number,1) and RIGHT(#Number,1) to access each digit. If it's not, comment back and I'll give you some help with the loop you'll need.
More pressing an issue is that you're expecting 2, but the result of 8 mod 10 is 8. If you're looking for 2, the sum is 10 mod 8 (10 % #Result).
In any case, hit me back if this doesn't answer exactly what you wanted.
Try this
declare #myNumber float,#result float
set #myNumber = 62
select
#result = (case when len(#myNumber) = 1 then #myNumber
else (#myNumber /10) + cast(#myNumber as int) % 10 end)
select [Output] = STUFF(
cast(#result as varchar(50))
,1
,charindex('.',cast(#result as varchar(50)))
,'')
Output
2
Hope this helps
And if u just want to add 2 numbers try this(though it has been implemented above)
declare #myNumber int,#result int
set #myNumber = 62
select
Result = (case when len(#myNumber) = 1 then #myNumber
else (#myNumber /10) + #myNumber % 10 end)
Result
8
So I guess you want something like this - parse the string representing your number, adding up the individual digits as integer values. This gives you a total result at the end - then you do whatever you need to do with that. This code works for any length of string (up to 50 characters = 50 digits in your original number):
DECLARE #Number INT
SET #Number = 62
DECLARE #NumString VARCHAR(50)
SET #NumString = CAST(#Number AS VARCHAR(50))
DECLARE #Index INT
SET #Index = 1
DECLARE #Sum INT
SET #Sum = 0
WHILE #Index <= LEN(#NumString)
BEGIN
SET #Sum = #Sum + CAST(SUBSTRING(#NumString, #Index, 1) AS INT)
SET #Index = #Index + 1
END
SELECT #Sum AS 'Sum of all digits'
With the initial value of "62" for #Number, I get a result of 8 - now you can continue on using that value.
If you need this function often, I would probably encapsulate it into a user-defined function so you can call it from everywhere in your code.