IF equals or clause - sql

I have a stored procedure that runs two separate queries and puts the data into two temporary tables. I then have an IF statement below that, depending on the outcome will display one of the two tables.
DECLARE #DATASET1 AS FLOAT
DECLARE #DATASET2 AS FLOAT
SET #DATASET1 = (SELECT SUM(PREM) FROM #Prem1)
SET #DATASET2 = (SELECT SUM(PREM) FROM #Prem2)
IF (#DATASET1 = 0)
BEGIN
SELECT DATE,
SUM(PREM) AS PREM
FROM #DATASET2
GROUP BY YEAR, MONTH, DATE
ORDER BY YEAR, MONTH
END
IF (#DATASET2 = 0)
BEGIN
SELECT DATE,
SUM(PREM) AS PREM
FROM #DATASET1
GROUP BY YEAR, MONTH, DATE
ORDER BY YEAR, MONTH
END
This was working well until I hit some output on dataset1 that didn't produce 0 but just produced no data at all.
So I was wondering if it is possible to update this part of the query to almost say:
IF (#DATASET1 = 0 or '')
I have tried something like that but doesn't seem to work, hence my question.

Your scalar aggregate query (SELECT SUM(PREM) FROM #Prem1) will return a NULL value if there is no record in the table or of column PREM contains only NULL values.
You can handle NULL with IS NULL, like so:
IF (#DATASET1 IS NULL OR #DATASET1 = 0)
You can also use COALESCE():
IF (COALESCE(#DATASET1, 0) = 0)

You can achieve it by using ISNULL()
IF (ISNULL(#DATASET1, 0) = 0)
Syntax: ISNULL(expression, value)
Parameter Description
expression Required. The expression to test whether is NULL
value Required. The value to return if expression is NULL

Related

Condition for a SQL query to check if dates are between prior period and current month and execute subqueries based on given gate

DECLARE #Todaydate DATE
SET #Todaydate = '12/31/2017'
SELECT
CASE
WHEN DATEDIFF(dd,#Todaydate,getdate()) >= 31
THEN (SELECT a.CU, , b.abc
FROM histhold a, security b
WHERE T_QUANTITY_P <> 0
AND ACCOUNTING_DATE = '04/30/2018'
AND a.cu = b.CU)
ELSE ''
END
Just do the logic in the WHERE clause:
SELECT a.CU, , b.abc
FROM histhold a
INNER JOIN security b
ON a.cu = b.CU
WHERE T_QUANTITY_P <> 0
AND ACCOUNTING_DATE = '04/30/2018'
AND DATEDIFF(dd,#Todaydate,getdate()) >= 31;
Unless this is part of some larger procedure/script I can't imagine a reason why you would only want to execute a query given certain conditions (as opposed to executing the query and restricting the results based on those conditions potentially returning an empty recordset).

Query returning null values but there is no error

I am picking values from a column TRANSAMT from the table GLPJD. The value can be negative in the table but when it's negative, I have to make it positive and when its positive, I leave it like that. The result being returned in NULL, what is left in the query. It is a subquery
declare #FY int
set #FY = 2016
SELECT
DbName, District,
(SELECT
CASE
WHEN (TRANSAMT < 0)
THEN ISNULL(SUM(TRANSAMT) * -1, 0)
ELSE ISNULL(SUM(TRANSAMT), 0)
END
FROM
GLPJD
LEFT JOIN
GLAMF ON GLPJD.ACCTID = GLAMF.ACCTID
WHERE
GLPJD.AUDTORG = D.DbName
AND GLPJD.ACCTID = 110002
AND GLPJD.FISCALYR < #FY
GROUP BY
TRANSAMT) AS TRANSAMT
FROM
Districts D
Results of the query:
Your error comes probably from the fact that performing a SUM while having NULL values returns a NULL result. So you should use the ISNULL part inside SUM, and not the other way around.
Also you may consider using the function ABS, so you could get rid of the CASE part. My approach would be changing this part from your current code:
SELECT
CASE
WHEN (TRANSAMT < 0)
THEN ISNULL(SUM(TRANSAMT) * -1, 0)
ELSE ISNULL(SUM(TRANSAMT), 0)
END
To just:
SELECT SUM(ABS(ISNULL(TRANSAMT, 0)))
sum function omits null values
look:
http://sqlfiddle.com/#!4/0a806/1

If value return the value. If a record not exists or when column is null, return 0 in Sql Server - different ways

I want to return 0 if there is no record or if the Column1 is null.
select #var = Column1
from myschema.mytable
where Id = #suppliedId;
select isnull(#var, 0);
The above code outputs 0 if if Column1 is null. Or if a row is not found
Whereas I tried to save some keystrokes but it resulted in,
select isnull(Column1, 0)
from myschema.mytable
where Id = #suppliedId;
The above code outputs null if Column1 is null or when there is no row
Any ideas what is wrong here ? Or is there any shorter way of writing the first code ?
You can do
SELECT #var = ISNULL(MAX(Column1), 0)
FROM myschema.mytable
WHERE Id = #suppliedId;
A scalar aggregate always returns a single row even if the underlying query returns zero rows.
Not really saving key strokes, but something like this could help :-)
SELECT TOP 1 tbl.field
FROM
(
SELECT 0 AS inx, 'no record' AS field
--if only one row is possible, than set '1' literally
UNION SELECT ROW_NUMBER() OVER(ORDER BY mytable.orderfield), ISNULL(mytable.Land,'is null')
FROM mytable
WHERE IDENTITY = #suppliedID
) AS tbl
ORDER BY tbl.inx DESC

Handle SQL SUM operator on varchar operands

I want to calculate aggregate functions SUM and COUNT on some table columns. The problem is that the columns are selected dynamically and hence they can be of varchar type. In this situation, COUNT is appliable but SUM isn't. How can I handle this using SQL? I want somthing like:
IF varcharColumn IS typeof(varchar) THEN -1 ELSE SUM(varcharColumn)
So you can do something like this:
DECLARE #varCharColumn VARCHAR(MAX) = (SELECT TOP 1 varcharColumn FROM SomeTable)
IF (ISNUMERIC(#varCharColumn) = 1 )
BEGIN
SELECT COUNT(varcharColumn) AS CountNumber, SUM(varcharColumn) AS SumNumber
FROM SomeTable
END
ELSE
BEGIN
SELECT COUNT(varcharColumn) AS CountNumber, -1 AS SumNumber
FROM SomeTable
END
Here are some info on ISNUMERIC

How to Short-Circuit SQL Where Clause

I am trying to perform the following query in SQL server:
declare #queryWord as nvarchar(20) = 'asdas'
SELECT * FROM TABLE_1
WHERE (ISDATE(#queryWord) = 1)
AND TABLE_1.INIT_DATE = CONVERT(Date, #queryWord)
This obviously causes an error because 'asdas' cannot be converted to Date. Although, I was expecting a different behavior. That is, because ISDATE(#queryWord) = 1 is false, I was expecting SQL to not check the second condition, but apparently, it does.
I know there are some other ways to perform this query but this is not my question. I wonder if there is some way to do not check the second condition is the first one does not satisfy. I am curious because I thought that SQL already did this.
SQL Server does not do short-circuiting (nor should it).
If you need it to not try something under some circumstances, you need to force that in the way that you write your query.
For this query the easiest fix would be to use a CASE expression in your WHERE clause.
declare #queryWord as nvarchar(20) = 'asdas'
SELECT * FROM TABLE_1
WHERE TABLE_1.INIT_DATE = (CASE WHEN ISDATE(#queryWord) = 1
THEN CONVERT(Date, #queryWord)
ELSE NULL END)
Off-hand, CASE and query-nesting are the only two supported ways that I can think of to force an order of evaluation for dependent conditions in SQL.
I Guess you could do it in 2 passes:
declare #queryWord as nvarchar(20) = 'asdas'
select
*
from
(
SELECT * FROM TABLE_1
WHERE (ISDATE(#queryWord) = 1) ) t1
where t1.INIT_DATE = CONVERT(Date, #queryWord)
So your inner query runs the first test and the outer query the second. In a single query, I don't believe there is any way to force any order of evaluating conditions.
Why not do a CASE in the WHERE condition?
DECLARE #tester TABLE (
theDate DATE,
theValue INT
)
INSERT INTO #tester VALUES ('2013-10-17', 35)
INSERT INTO #tester VALUES ('2013-10-16', 50)
INSERT INTO #tester VALUES ('2013-10-15', 2)
declare #queryWord as nvarchar(20) = 'asdas'
SELECT *
FROM #tester
WHERE theDate =
CASE
WHEN ISDATE(#queryWord) = 1 THEN CONVERT(Date, #queryWord)
ELSE theDate
END
SET #queryWord = '2013-10-17'
SELECT *
FROM #tester
WHERE theDate =
CASE
WHEN ISDATE(#queryWord) = 1 THEN CONVERT(Date, #queryWord)
ELSE theDate
END
It can be "simulated" with a CASE statement. But you have to make the first condition giving a TRUE value to avoid checking of the 2nd condition :
declare #queryWord as nvarchar(20) = 'asdas'
SELECT *
FROM TABLE_1
WHERE (CASE
WHEN ISDATE(#queryWord) = 0 THEN 0
WHEN TABLE_1.INIT_DATE = CONVERT(Date, #queryWord) THEN 1
ELSE 0 END) = 1
There is no defined evaluation order in a SQL statement -- except in the case of case expressions, and even there the order isn't so much defined as the result guaranteed. The conditions in your where clause could theoretically be done in parallel or alternating order.
Case expressions differ not by having a defined order, but by having a guaranteed result. IOW, case when 1=1 then 0 When longrunningfunction() = 1 then 2 end is guaranteed to return zero, but there is no promise not to run the longrunningfunction.