How to return 'blank' using Sum function in Sql, if Sum is resulting 0 in SQL - sql

I am using Sql Server 2008. I am adding some column value using Sum function. Like the code below:
SELECT 'RCOAuthorizer LMS',
'' AS Consumer_Loan,
'' AS Auto_Loan,
'' AS Credit_Card,
SUM(CASE
WHEN sq2.loan_type = 'Loan Amendment' THEN sq2.user_count
ELSE ''
END ) AS Loan_Amendment,
SUM(CASE
WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count
ELSE ''
END ) AS Pre_Payment,
SUM(CASE
WHEN sq2.loan_type = 'Corporate Credit card' THEN sq2.user_count
ELSE ''
END ) AS Corporate_Credit_card,
'' AS Auto_Payment_Release,
'' AS Car_Mulkiya
FROM
( SELECT 'RCOAuthorizer' AS ws_name,
'Loan Amendment' AS loan_type,
COUNT (DISTINCT a.bpm_referenceno) AS user_count,
a.user_id AS user_id
FROM BM_LMS_DecisionHistoryGrid a
INNER JOIN
( SELECT m.bpm_referenceno
FROM BM_LMS_EXTTABLE m
WHERE m.request_type = 'Loan Amendment' ) sq1 ON a.bpm_referenceno = sq1.bpm_referenceno
WHERE workstep_name = 'RCOAuthorizer'
GROUP BY a.user_id
UNION SELECT 'RCOAuthorizer',
'Pre-Payment',
COUNT (DISTINCT a.bpm_referenceno), a.user_id
FROM BM_LMS_DecisionHistoryGrid a
INNER JOIN
( SELECT m.bpm_referenceno
FROM BM_LMS_EXTTABLE m
WHERE m.request_type = 'Pre-Payment' ) sq1 ON a.bpm_referenceno = sq1.bpm_referenceno
WHERE workstep_name = 'RCOAuthorizer'
GROUP BY a.user_id
UNION SELECT 'RCOAuthorizer',
'Corporate Credit card',
COUNT (DISTINCT a.bpm_referenceno), a.user_id
FROM BM_LMS_DecisionHistoryGrid a
INNER JOIN
( SELECT m.bpm_referenceno
FROM BM_LMS_EXTTABLE m
WHERE m.request_type = 'Corporate Credit card' ) sq1 ON a.bpm_referenceno = sq1.bpm_referenceno
WHERE workstep_name = 'RCOAuthorizer'
GROUP BY a.user_id ) sq2
GROUP BY sq2.ws_name
The above query will return Sum of all the numbers available in 'a' column. But in case, there is no record, then it will return '0' as result.
I require that if there is no record, it must show blank instead of showing '0'. How to handle the same.

To start, you don't need an ISNULL with a back value of 0 (the neutral for adding) inside a SUM aggregate, as the SUM already ignores NULL values. So SUM(ISNULL(Column, 0)) is equal to SUM(Column) (but different from ISNULL(SUM(Column), 0)!).
Seems that you want a VARCHAR result instead of a numeric one. You can solve this with a CASE.
Select
CASE WHEN Sum(a) = 0 THEN '' ELSE CONVERT(VARCHAR(100), Sum(a)) END
from
table;
If you don't want to repeat the SUM expression:
;WITH SumResult AS
(
Select CONVERT(VARCHAR(100), Sum(a)) AS SumTotal
from table
)
SELECT
CASE WHEN R.SumTotal = '0' THEN '' ELSE R.SumTotal END
FROM
SumResult AS R
Keep in mind that in these both cases, if there is no record to calculate the sum from, the result will be NULL.
EDIT: There is no point in adding '' inside your SUM, as it's converted to 0 to be able to sum. The solution is still the same as I posted before.
Change
SUM(CASE
WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count
ELSE ''
END ) AS Pre_Payment,
for
CASE
WHEN SUM(CASE WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count END) = 0 THEN ''
ELSE CONVERT(VARCHAR(100), SUM(CASE WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count)) END AS Pre_Payment,

Just try this ( use isnull again ):
Select isnull(Sum(isnull(a,0)),0) from table_;
I used table_ instead of table, because table is a reserved keyword.
SQL Fiddle Demo

Related

Apply Pivot on multiple colums and rows

This is my sample table and I want to pivot the Leave column and get max to leave opening, debit and credit value and balance leaves
Formula for Balance Leaves: leaveopen + leavecr - leaveused - leavedb
Below is the expected output
so far I have managed to get leaveopening but not able to get all the values in a single query
select e.Code,e.FName + ' ' + case when e.LName !=null then e.LName else ' ' end [Name],l.*
from .EmployeeDetail e
inner join (select * from(select Leave,LeaveOpen,EmployeeId,CompanyId from LeaveOpening where Leave in ('PL','SL','Coff') and employeeid=534 ) src pivot(max(LeaveOpen) for Leave in (PL,SL,Coff)) as src2) l on e.Id = l.EmployeeId and e.CompanyId = l.CompanyId and employeeid=534
Here is a short example using Case statement instead of Pivot.
select EmployeeId
,MAX(CASE WHEN Leave = 'PL' THEN LeaveOpen ELSE 0 END) AS [PL Opening]
,MAX(CASE WHEN Leave = 'PL' THEN LeaveCredit ELSE 0 END) AS [PL Credit]
from LeaveOpening
group by EmployeeID

How to replace a subselect with a join in a case statement in SQL?

I have a SQL query with a case statement. The case statement has a subquery. I want to replace (delete) the subselect with a join. It is possible? How can i do it?
The Query:
SELECT tablex.Abnumber, CASE WHEN Abdate is not null AND isnull(Abnumber,0) > 1 AND Abdate < (SELECT Abdate FROM t_tablex WHERE Annumber = #Annumber AND Abnumber= #Abnumber-1) THEN 'bla bla' ELSE '' END
FROM t_tablex AS tablex
WHERE (#Annumber IS NULL OR tablex.Annumber= #Annumber)
AND (#AbnumberIS NULL OR tablex.Abnumber= #Abnumber)
SELECT tablex.Abnumber,
CASE WHEN isnull(Abnumber,0) > 1 AND Abdate < a.Abdate THEN 'bla bla' ELSE '' END
FROM t_tablex AS tablex
LEFT JOIN (SELECT Abdate
FROM t_tablex
WHERE Annumber = #Annumber AND Abnumber= #Abnumber-1
) A ON A.Annumber = tablex.Annumber AND a.Abnumber = tablex.Abnumber
WHERE tablex.Annumber= #Annumber
AND tablex.Abnumber= #Abnumber
I suspect that LAG() does what you want:
SELECT x.Abnumber,
(CASE WHEN x.Abdate is not null AND
x.Abnumber > 1 AND
x.Abdate < prev_Abdate
THEN 'bla bla'
ELSE ''
END)
FROM (SELECT x.*,
LAG(Abdate) OVER (PARTITION BY Annumber ORDER BY Abnumber) as prev_Abdate)
FROM t_tablex x
) x
WHERE (#Annumber IS NULL OR x.Annumber= #Annumber) AND
(#Abnumber IS NULL OR x.Abnumber = #Abnumber);
This is not exactly equivalent to your query, unless some assumptions are made about the data. However, I suspect it is actually what you intend.
Thanks for the answers. I tried some things and found the following solutions:
Solution 1 (replace subselect with inner join):
SELECT tablex.Abnumber,
CASE WHEN tablex.Abdate is not null
AND isnull(tablex.Abnumber,0) > 1
AND tablex.Abdate < tablex2.Abdate
THEN 'bla bla'
ELSE '' END
FROM t_tablex AS tablex
INNER JOIN t_tablex as tablex2
ON tablex.Annumber = tablex2.Annumber
AND tablex.Abnumber = tablex2.Abnumber + 1
WHERE tablex.Annumber = ISNULL( #Annumber, tablex.Annumber)
AND tablex.Abnumber = ISNULL( #Abnumber, tablex.Abnumber)
Solution 2 (with LAG()):
SELECT base.*
FROM (
SELECT tablex.Abnumber,
CASE WHEN tablex.Abdate is not null
AND tablex.Abnumber > 1
AND tablex.Abdate < LAG( tablex.Abdate, 1 ) OVER ( PARTITION BY tablex.Annumber ORDER BY tablex.Abnumber)
THEN 'bla bla'
ELSE '' END AS ERG
FROM t_tablex AS tablex
WHERE tablex.Annumber = ISNULL( #Annumber, tablex.Annumber )
AND tablex.Abnumber BETWEEN ISNULL( #Abnumber , tablex.Abnumber) - 1
AND ISNULL( #Abnumber, tablex.Abnumber )
) base
WHERE
base.Abnumber = ISNULL( #Abnumber, base.Abnumber )

SQL Server sum and subtract prevent null results

I'm using this code:
SELECT
(SELECT SUM(TrnQty) AS Total
FROM InventoryTrans
WHERE InventoryItemID = (select MAX(InventoryItemID)
from inventorymaster)
AND CustomerID = '0') -
(SELECT SUM(TrnQty) AS Total
FROM InventoryTrans
WHERE InventoryItemID = (select MAX(InventoryItemID)
from InventoryMaster)
AND CustomerID > '0'
)
If the result of one them is NULL i take totally result NULL. How can I SUM if one of them is Null? Should I use CASE or something?
Here is a correct way to do it
SELECT Sum(CASE
WHEN customerid = '0' THEN trnqty
ELSE 0
END) - Sum(CASE
WHEN customerid > '0' THEN trnqty
ELSE 0
END) AS Total
FROM inventorytrans
WHERE inventoryitemid = (SELECT Max (inventoryitemid)
FROM inventorymaster)
EDIT:
I [#GordonLinoff] am providing a slightly simpler version of this answer. The use of conditional aggregation is correct, but there is a simpler way of writing it:
SELECT SUM(CASE WHEN it.customerid = '0' THEN it.trnqty
WHEN it.customerid > '0' THEN - it.trnqty
ELSE 0
END) as Total
FROM inventorytrans it
WHERE it.inventoryitemid = (SELECT Max(im.inventoryitemid)
FROM inventorymaster im
)
use
SELECT coalesce(SUM(TrnQty), 0) ...
You can also use
SELECT ISNULL(SUM(TrnQty),0)...
Simply wrap your existing inner select statements in an ISNULL function. It is simple to implement and your intent is clear, if your SELECT returns a null value, use 0.
SELECT
IsNull(
(
SELECT SUM(TrnQty) AS Total
FROM InventoryTrans
WHERE InventoryItemID =
(
select MAX (InventoryItemID) from inventorymaster
)
and CustomerID='0'
),0) -
IsNull(
(
SELECT SUM(TrnQty) AS Total
FROM InventoryTrans
WHERE InventoryItemID =
(
select MAX (InventoryItemID) from InventoryMaster
)
and CustomerID > '0'
),0)
Is this a great example of SQL, not really, but you can see how wrapping the select statements with IsNull is a minor change to your existing query to give you the results you need.
This query could be re-written into a single set based operation, here's my go at it:
SELECT SUM(CASE customerid WHEN '0' THEN -TrnQty ELSE TrnQty END) AS Total
FROM InventoryTrans
WHERE InventoryItemID =
(
select MAX (InventoryItemID) from inventorymaster
)
It is not necessary in this new query to check for null, (either with IsNull or Coalesce) unless you need to ensure that the end result is not null, this query will only return null if ALL of the TrnQty fields are also null. If that is a problem for you logic, wrap the SUM function in an IsNull function as well.

counting records on the same table with different values possibly none sql server 2008

I have a inventory table with a condition i.e. new, used, other, and i am query a small set of this data, and there is a possibility that all the record set contains only 1 or all the conditions. I tried using a case statement, but if one of the conditions isn't found nothing for that condition returned, and I need it to return 0
This is what I've tried so far:
select(
case
when new_used = 'N' then 'new'
when new_used = 'U' then 'used'
when new_used = 'O' then 'other'
end
)as conditions,
count(*) as count
from myDB
where something = something
group by(
case
when New_Used = 'N' then 'new'
when New_Used = 'U' then 'used'
when New_Used = 'O' then 'other'
end
)
This returns the data like:
conditions | count
------------------
new 10
used 45
I am trying to get the data to return like the following:
conditions | count
------------------
new | 10
used | 45
other | 0
Thanks in advance
;WITH constants(letter,word) AS
(
SELECT l,w FROM (VALUES('N','new'),('U','used'),('O','other')) AS x(l,w)
)
SELECT
conditions = c.word,
[count] = COUNT(x.new_used)
FROM constants AS c
LEFT OUTER JOIN dbo.myDB AS x
ON c.letter = x.new_used
AND something = something
GROUP BY c.word;
try this -
DECLARE #t TABLE (new_used CHAR(1))
INSERT INTO #t (new_used)
SELECT t = 'N'
UNION ALL
SELECT 'N'
UNION ALL
SELECT 'U'
SELECT conditions, ISNULL(r.cnt, 0) AS [count]
FROM (
VALUES('U', 'used'), ('N', 'new'), ('O', 'other')
) t(c, conditions)
LEFT JOIN (
SELECT new_used, COUNT(1) AS cnt
FROM #t
--WHERE something = something
GROUP BY new_used
) r ON r.new_used = t.c
in output -
new 2
used 1
other 0
You can do it as a cross-tab:
select
sum(case when new_used = 'N' then 1 else 0 end) as N,
sum(case when new_used = 'U' then 1 else 0 end) as U,
sum(case when new_used = 'O' then 1 else 0 end) as Other
from myDB
where something = something

Case statement problem to show values without null in a row

select CASE WHEN ( rtt.us_code = 's' )
THEN rtt.name
ELSE '' END AS input_tax_name,
CASE WHEN ( rtt2.us_code = 'r')
THEN rtt2.name
ELSE '' END AS output_tax_name,
CASE WHEN ( rtt.us_code = 's' )
THEN rtt.acc_id
ELSE 0 END AS input_tax_rate,
CASE WHEN ( rtt2.us_code = 'r')
THEN rtt2.acc_id
ELSE 0 END AS output_tax_rate
from supplier_item si
JOIN ret_tx_type rtt
ON si.ret_tx_type_id = rtt.ret_tx_type_id
JOIN ret_tx_type rtt2
ON si.ret_tx_type_id = rtt2.ret_tx_type_id
where si.ret_tx_type_id is not null
I am trying to display input and output tax in the same row for a report depends on us_code is 'r' and 's'.
But i am getting the results like
if input tax is there ...output tax column will be null
if output tax is there ...input tax column will be null
i am want to get the both in same row and no need to make null in any rows
please help
SELECT
MAX(CASE rtt.us_code WHEN 's' THEN rtt.name END) AS input_tax_name,
MAX(CASE rtt.us_code WHEN 'r' THEN rtt.name END) AS output_tax_name,
MAX(CASE rtt.us_code WHEN 's' THEN rtt.acc_id END) AS input_tax_rate,
MAX(CASE rtt.us_code WHEN 'r' THEN rtt.acc_id END) AS output_tax_rate
FROM supplier_item si
INNER JOIN ret_tx_type rtt
ON si.ret_tx_type_id = rtt.ret_tx_type_id
GROUP BY ??? /* here you should supply a column,
presumably in 'si', that is common
to both of the related 'r'- and
's'-tax records */
You need to add a GROUP BY to your query on something (possibly GROUP BY si.id?)
And put the CASE statements into aggregates. e.g.
MAX(CASE WHEN ( rtt2.us_code = 'r')
THEN rtt2.acc_id
ELSE 0 END)