SQL query should return percentage but returns error - sql

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.

Related

Getting 0 instead of decimal when dividing a int by 100 in 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

Show data where the value is after the decimal point

I would like to do (select value from table where...) where the value of a given experiment is not an integer, but it is decimal
You can use FLOOR function to do this. It will round up your numbers, so you can pick only this that are not integers.
create table #t (i decimal(12,6))
insert into #t values (1), (1.1)
select * from #t where FLOOR(i) <> i
You can do as
CREATE TABLE T( Val DECIMAL(10, 2));
INSERT INTO T VALUES
(10.10), (10);
SELECT *
FROM T
WHERE CAST(Val AS INT) <> Val
Returns: 10.10

SQL Server window function for running percentage

I know there are several examples of recursion with CTE and so on, but how can this be accomplished just by using window functions in SQL Server 2012:
CREATE TABLE #temp
(
ID INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
Percentage INT NOT NULL
)
DECLARE #Calculated MONEY = 1000
INSERT INTO #temp ( Percentage ) VALUES ( 100 )
INSERT INTO #temp ( Percentage ) VALUES ( 90)
INSERT INTO #temp ( Percentage ) VALUES ( 60)
INSERT INTO #temp ( Percentage ) VALUES ( 50)
INSERT INTO #temp ( Percentage ) VALUES ( 100)
And the result would be a running percentage like so (we are starting with $1000)
id percentage calculated
-- -------- ---------
1 100 1000
2 50 500
3 90 450
4 80 360
5 100 360
So the value for the next row is the percentage multiplied by the calculated value above that row. Can LAG be used on a computed alias?
Thanks,
You need a running product of the percentages instead of always comparing 2 consecutive rows, which is why LEAD and LAG won't work here.
You can use a windowed sum to keep a running product of the percentages against your variable to get your desired calculation:
SELECT
ID,
Expected,
EXP(SUM(LOG(CONVERT(FLOAT, Percentage) / 100)) OVER (ORDER BY ID)) * #Calculated AS Actual
FROM #Temp
Adding this to your sample code (with a column I added for your expected output):
CREATE TABLE #temp
(
ID INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
Percentage INT NOT NULL,
Expected MONEY NOT NULL
)
DECLARE #Calculated MONEY = 1000
INSERT INTO #temp ( Percentage, Expected ) VALUES ( 100 , 1000)
INSERT INTO #temp ( Percentage, Expected ) VALUES ( 50, 500)
INSERT INTO #temp ( Percentage, Expected ) VALUES ( 90, 450)
INSERT INTO #temp ( Percentage, Expected ) VALUES ( 80, 360)
INSERT INTO #temp ( Percentage, Expected ) VALUES ( 100, 360)
SELECT
ID,
Expected,
EXP(SUM(LOG(CONVERT(FLOAT, Percentage) / 100)) OVER (ORDER BY ID)) * #Calculated AS Actual
FROM #Temp
This will yield your expected output:
ID Expected Actual
----------- --------------------- ----------------------
1 1000.00 1000
2 500.00 500
3 450.00 450
4 360.00 360
5 360.00 360
you can use recursive cte to get the desired result
with cte
as
(
select id, percentage, 1000 as calculated
from #temp
where id =1
union all
select t.id, t.percentage, t.percentage*cte.calculated/100 as calculated
from #temp t
join cte
on t.id = cte.id+1
)
select * from cte
I'm afraid, widow functions won't help here (at least they won't make it simple). The easiest way to achieve your goal is update statement with double assignment:
alter table #temp add VAL decimal
declare #val decimal = 1000
update t set
#val = VAL = #val * Percentage / 100
from (select top 100 percent * from #temp order by id) as t
select * from #temp

SQL query to know skipped number

Hi im new to SQL query i only know simple query.
My question is it possible to SELECT skipped check number EX2001,EX2002,EX2004
select result will show EX2003.
thanks in advance, sorry for my english.
you can answer algorithm only, ill try to implement it to SQL.
example:
SELECT * FROM SETTLEMENT WHERE checkno not in (between ex2001 and ex2900)
is it possible like this? im using MS SQL 2008.
create table sequence(st varchar(50))
insert into sequence values('EX2001');
insert into sequence values('EX2002');
insert into sequence values('EX2004');
insert into sequence values('EX2005');
insert into sequence values('EX2008');
Assuming your original table name is sequence with only one field, you can modify as per your needs
Try below
DECLARE #all TABLE
(
st varchar(20)
)
declare #start int
declare #end int
declare #str varchar(20)
set #start=2000 //define starting point
set #end=2010 //define end point
while(#start<#end)
BEGIN
SET #start=#start+1
set #str='EX'+cast(#start as varchar(20))
INSERT INTO #all VALUES (''+#str+'')
END
SELECT * from #all
except
select * from sequence
output
st
EX2003
EX2006
EX2007
EX2009
EX2010
if you need hard coded values in query then it can be done like (as you did not posted any code so here is a simple query). you can use IN() or NOT IN() in sql
select * from table where check_number not in ('EX2001','EX2002','EX2004' );
Since SQL engine is not mentioned, this answer is only for Oracle 11G
Option 1: With hierarchical queries
See Fiddle here
CREATE TABLE TEST1 ( A VARCHAR2 ( 9 ) );
INSERT INTO
TEST1
VALUES
( 'EX2001' );
INSERT INTO
TEST1
VALUES
( 'EX2002' );
INSERT INTO
TEST1
VALUES
( 'EX2004' );
COMMIT;
WITH TEST2
AS (SELECT
TO_NUMBER(SUBSTR ( A,
3 ))
AS A
FROM
TEST1)
SELECT
MIN_A
- 1
+ LEVEL
FROM
(SELECT
MIN ( A ) MIN_A,
MAX ( A ) MAX_A
FROM
TEST2)
CONNECT BY
LEVEL <= MAX_A
- MIN_A
+ 1
MINUS
SELECT A FROM TEST2;
Option 2: With Oracle analytics function
See Fiddle here
WITH T
AS (SELECT
TO_NUMBER(SUBSTR ( A,
3 ))
AS SNO,
SYSDATE AS SDATE
FROM
TEST1)
SELECT
SDATE,
SNO
+ 1
FIRST_MISSING,
DECODE ( NEXT_SNO
- 1,
SNO
+ 1, TO_NUMBER ( NULL ),
NEXT_SNO
- 1 )
LAST_MISSING
FROM
(SELECT
SDATE,
SNO,
LAG ( SNO )
OVER ( PARTITION BY SDATE
ORDER BY SNO )
LAST_SNO,
LEAD ( SNO )
OVER ( PARTITION BY SDATE
ORDER BY SNO )
NEXT_SNO
FROM
T)
WHERE
NVL ( NEXT_SNO,
SNO
+ 1 ) <> SNO
+ 1;

Find missing numbers in a column

I have this column in T-SQL:
1
2
3
7
10
have SQl a function for detect the missing numbers in the sequence 4,5,6 and 8,9
I have try
something like
if ( a-b >1 ) then we have a missing number
with coalesce but i dont understand .
Thanks by any orientation
You can try this:
DELCARE #a
SET #a = SELECT MIN(number) FROM table
WHILE (SELECT MAX(number) FROM table ) > #a
BEGIN
IF #a NOT IN ( SELECT number FROM table )
PRINT #a
SET #a=#a+1
END
The following query will identify where each sequence starts and the number that are missing:
select t.col + 1 as MissingStart, (nextval - col - 1) as MissingSequenceLength
from (select t.col,
(select min(t.col) from t t2 where t2.col > t.col) as nextval
from t
) t
where nextval - col > 1
This is using a correlated subquery to get the next value in the table.
I know this is a late answer, but here is a query that uses recursive table expressions to get the missing values between the minimum and maximum values in a table:
WITH CTE AS
(
--This is called once to get the minimum and maximum values
SELECT nMin = MIN(t.ID), MAX(t.ID) as 'nMax'
FROM Test t
UNION ALL
--This is called multiple times until the condition is met
SELECT nMin + 1, nMax
FROM CTE
WHERE nMin < nMax
)
--Retrieves all the missing values in the table.
SELECT c.nMin
FROM CTE c
WHERE NOT EXISTS
(
SELECT ID
FROM Test
WHERE c.nMin = ID
)
This was tested with the following schema:
CREATE TABLE Test
(
ID int NOT NULL
)
INSERT INTO Test
Values(1)
INSERT INTO Test
Values(2)
INSERT INTO Test
Values(3)
INSERT INTO Test
Values(7)
INSERT INTO Test
Values(10)