Getting 0 instead of decimal when dividing a int by 100 in SQL - sql

I have a column Column1 of an int type in myTable with a value of, let's say, 25.
When inserting cast(Column1 as decimal)/100 into a temp table #tempTbl as following
create table #tempTbl
(
Column1 decimal
)
Insert into #tempTbl
select cast(Column1 as decimal)/100
from myTable
I see 0 in the Column1 of a temp table instead of 0.25
When I try select cast(25 as decimal)/100, I'm getting 0.25
What am I doing wrong?

I would suggest:
select Column1 / 100.0
SQL Server does integer division (as you have discovered). Just including a decimal place in a constant or multiplying by 1.0 usually resolves the issue.

Try
select cast(Column1 as decimal)/100.0
If execute
select 25/100.0;
It returns
(No column name)
0.250000
Please see this code. The decimel length was specified in the DDL of the temp table
create table #tempTbl
(
Column1 decimal(8,2)
)
Insert into #tempTbl
select 25
select Column1/100.0 from #tempTbl;
Output
0.2500000

Related

SQL query should return percentage but returns error

I have the following lines of code:
ROUND((((SUM(VALOR_2)) - SQLTMP.VALOR_1) / SQLTMP.VALOR_1) * 100, 2)
I was hoping it would return a percentage, but it returns an ERROR instead... Any ideas on what's wrong?
Depending on your inputs you can try addapting this solution :
CREATE TABLE #TMP (
val1 int,
val2 int
);
INSERT INTO #TMP
VALUES (1,2),(1,3),(1,4),(2,5),(2,6)
GO
-- Your code begins here
WITH tmp_table AS (
SELECT
val1 AS val1,
SUM(COLAESCE(val2, 0)) AS sum_val2
FROM #TMP
GROUP BY val1,val2
)
SELECT ROUND((sum_val2 - val1)/val1,2) FROM tmp_table;
-- Your code ends here
GO
DROP TABLE #TMP
select
round(v1/(v2*1.0), 2) as pct
from table
-- multiplying by 1.0 converts the int to decimal, round limits it to 2 places.

Add empty rows to results

I want to add empty rows to results fetched from a select statement. For example, if the select query fetch 4 rows then 2 empty rows needs to be fetched. Objective should be the number of rows fetched should be 6 every time. The number of rows fetched will be 6 maximum if there are 6 rows with data.
Any idea?
In SQL-SERVER You can create temp table to update It with empty rows and you can use WHILE to insert desired number of rows with empty values. Something like:
-- Create temp table to update data with empty rows
CREATE TABLE #HoldEmptyRows
(
Id NVARCHAR(20),
CustomerName NVARCHAR(20),
CustomerEmail NVARCHAR(20)
)
-- Insert data from SourceTable to temp
INSERT INTO #HoldEmptyRows
SELECT * FROM SourceTable
-- Do while count from temp table < of desired number insert empty rows
WHILE ((SELECT COUNT(*) cnt FROM #HoldEmptyRows) < 6)
BEGIN
INSERT INTO #HoldEmptyRows VALUES ('', '', '')
END
SELECT * FROM #HoldEmptyRows
DEMO AT SQL FIDDLE
Try the below logic:
with cte as
(
select 0 as col1
union all
select col1+1 from cte where cte.col1<10
)
select * into #temp1 from cte
create table #test
(rownum int,col1 varchar(100))
declare #i int=1
while (#i<=6)
begin
insert into #test
select * from
(select row_Number() over (order by (Select 0))rownum, * from #temp1)x
where rownum=#i
Set #i=#i+1
end
select case when rownum>4 then '' else col1 end as col1 from #test

Tally Table in SQL

I want to create a bunch of data with Tally table in SQL (sql2008) and definitely need help.
First of all, I have this table which contains 2 columns.
{
AcctNum (nchar(30), null),
DataInfo (nchar(745), null)
}
While I don't care the data in the DataInfo column, I do want to add about 10k of row into the table with unique AcctNum on each row.
The problem though is I need to keep the length of the data in both column. For example, AcctNum column looks like "400000000000001 ". how do I increment the number while keep the "blank space"?
Not sure if I make much sense here, but please let me know and I will try to explain more, thanks!
Using a recursive common table expression :
-- set up a table variable for demo purpose
declare #t table (AcctNum nchar(30) null, DataInfo nchar(745) null);
-- insert the starting value
insert #t values ('400000000000001', null);
-- run the cte to generate the sequence
with cte (acctnum, num) as (
select acctnum, cast(acctnum as bigint) + 1 num -- starting value
from #t
union all
select acctnum, num+1 from cte
where num < cast(acctnum as bigint) + 10000 -- stopping value
)
-- insert data sequence into the table
insert #t (AcctNum, DataInfo)
select num, null from cte
option (maxrecursion 10000);
select * from #t;
The table variable #t will now contain acctnum 400000000000001 -> 400000000010001 as a contiguous sequence.

How to increment DateTime column by a second for every row?

Suppose that I have this Time value: 09:00:00
And I have a table with a column Time, and I have three records in it.
I want to update those 3 records with that time but with the Time value incremented in one second each time (for every record).
Something like this:
ColumnA ColumnB
1 09:00:00
2 09:00:01
3 09:00:02
How can I do that?
My Solution:
After some time working on my own solution, this is what I came up with
update tor1
set ColumnB = dateadd(s,tor2.inc, ColumnB)
from table1 tor1
inner join (select ColumnA, ROW_NUMBER() OVER (Order by ColumnA) as inc from table1) tor2 on tor1.ColumnA=tor2.ColumnA
You don't specify any particular ordering.
For undeterministic/undocumented results you could try the quirky update approach.
CREATE TABLE table1
(
ColumnB datetime NULL
);
INSERT INTO table1 DEFAULT VALUES;
INSERT INTO table1 DEFAULT VALUES;
INSERT INTO table1 DEFAULT VALUES;
DECLARE #ColumnB datetime;
SET #ColumnB = '19000101 09:00:00';
UPDATE table1
SET #ColumnB = ColumnB = DATEADD(s, 1, #ColumnB);
SELECT *
FROM table1;
DROP TABLE table1;
Otherwise you will need to use a cursor or find some way of simulating ROW_NUMBER in 2000.
Here's a version that uses a #temp table but doesn't use the unsupported quirky update (no offense Martin) and doesn't rely on magical identity ordering, which is not guaranteed (no offense Richard).
CREATE TABLE dbo.Whatever
(
ColumnA INT IDENTITY(1,1),
ColumnB DATETIME
);
INSERT dbo.Whatever(ColumnB) SELECT '09:00';
INSERT dbo.Whatever(ColumnB) SELECT '09:00';
INSERT dbo.Whatever(ColumnB) SELECT '09:00';
INSERT dbo.Whatever(ColumnB) SELECT '09:00';
INSERT dbo.Whatever(ColumnB) SELECT '09:00';
-- just to demonstrate a gap
DELETE dbo.Whatever WHERE ColumnA = 3;
SELECT w.ColumnA, w.ColumnB,
c = (SELECT COUNT(*) FROM dbo.Whatever WHERE ColumnA < w.ColumnA)
INTO #x
FROM dbo.Whatever AS w;
UPDATE w
SET ColumnB = DATEADD(SECOND, x.c, w.ColumnB)
FROM dbo.Whatever AS w
INNER JOIN #x AS x
ON x.ColumnA = w.ColumnA;
SELECT ColumnA, ColumnB FROM dbo.Whatever;
Results:
ColumnA ColumnB
------- -----------------------
1 1900-01-01 09:00:00.000
2 1900-01-01 09:00:01.000
4 1900-01-01 09:00:02.000
5 1900-01-01 09:00:03.000
If you can assume ColumnA is the number of seconds you need to add (or directly proportional like your example), then you can use that.
UPDATE myTable SET ColumnB = DATEADD(s, (ColumnA - 1), ColumnB)
If not, you will need to determine the rank of each column (plenty of results on google for that) and add the rank instead.
For SQL Server 2005 onwards, you can use the OVER clause to control the ordering of the updates.
;with T as (
    select *, rn=row_number() over (order by columnA)
    from Tbl)
update T
   set columnB = DateAdd(s, rn-1, '09:00:00');
SQL Fiddle
For SQL Server 2000, you can use a temporary table. Use INSERT INTO..SELECT to guarantee the computation of the IDENTITY column.
CREATE TABLE table1
(
ColumnA int,
ColumnB datetime NULL
);
INSERT INTO table1 values (1, null);
INSERT INTO table1 values (2, getdate());
INSERT INTO table1 values (3, '02:02:02');
create table #tmp (ColumnA int, ID int identity(0,1))
insert into #tmp
select ColumnA
from table1
order by ColumnA;
update a
set ColumnB = dateadd(s,t.ID,'09:00:00')
from #tmp t
join table1 a on a.ColumnA = t.ColumnA;
select * from table1;

How to convert a column header and its value into row in sql?

I have a table with columns say col1, col2, col3. The table has many rows in it.
Let's assume val1, val2, val3 is one such row. I want to get the result as
Col1, Val1
Col2, Val2
Col3, Val3
That is 3 rows - one for each column and its value.
I am using SQL Server 2008. I read about pivots. Are pivots a way to solve this problem? Can someone route me to some examples or solutions how to solve this problem?
Thanks a lot
Maybe something like this:
Test data
DECLARE #T TABLE(Col1 INT, Col2 INT, Col3 INT)
INSERT INTO #T
VALUES (1,1,1)
Query
SELECT
*
FROM
(
SELECT
t.Col1,
t.Col2,
t.Col3
FROM
#T AS t
) AS SourceTable
UNPIVOT
(
Value FOR Col IN
(Col1,Col2,Col3)
) AS unpvt
Output
1 Col1
1 Col2
1 Col3
To do this kind of thing read the following: Using PIVOT and UNPIVOT
Pivot function allow you to convert row values in from of column..
Also check : Dynamic Pivoting in SQL Server
Example :
create table #temptable(colorname varchar(25),Hexa varchar(7),rgb varchar(1), rgbvalue tinyint)
GO
insert into #temptable values('Violet','#8B00FF','r',139);
insert into #temptable values('Violet','#8B00FF','g',0);
insert into #temptable values('Violet','#8B00FF','b',255);
insert into #temptable values('Indigo','#4B0082','r',75);
insert into #temptable values('Indigo','#4B0082','g',0);
insert into #temptable values('Indigo','#4B0082','b',130);
insert into #temptable values('Blue','#0000FF','r',0);
insert into #temptable values('Blue','#0000FF','g',0);
insert into #temptable values('Blue','#0000FF','b',255);
SELECT colorname,hexa,[r], [g], [b]
FROM
(SELECT colorname,hexa,rgb,rgbvalue
FROM #temptable) AS TableToBePivoted
PIVOT
(
sum(rgbvalue)
FOR rgb IN ([r], [g], [b])
) AS PivotedTable;
Create a temproary table:
CREATE TABLE #table2
(
name NCHAR,
bonus INT
)
Now Select and execute the below statement if there is an empty.
SELECT * FROM #table2
INSERT INTO #table2 (name,bonus) VALUES ('A',10)
INSERT INTO #table2 (name,bonus) VALUES ('B',20)
INSERT INTO #table2 (name,bonus) VALUES ('C',30)
After insert the values into table. select and execute the below line if you get records:
SELECT * FROM #table2
Input:
name bonus
A 10
B 20
C 30
Change the input into like this result
Result:
Cost A B C
Bonus 10 20 30
By using this code:
SELECT 'Bonus' AS Cost,
[A],[B],[C]
FROM
(SELECT name, Bonus
FROM #table2) AS TempTbl
PIVOT
(
AVG(bonus)
FOR [name] IN ([A],[B],[C])
) AS PivotTable;