SQL Do not return column if value is zero - sql

This query returns one row with columns Ready, Processing, Complete, Failed and Error with totals for each. Is there a way to rewrite this query so that columns that have a total of zero are not returned?
I'm using this to populate the mschart control and I don't wan't labels on the chart if there are 0 instances of that category.
SELECT
SUM(CASE WHEN Status = 'R' THEN 1 ELSE 0 END) AS Ready,
SUM(CASE WHEN Status = 'P' THEN 1 ELSE 0 END) AS Processing,
SUM(CASE WHEN Status = 'C' THEN 1 ELSE 0 END) AS Complete,
SUM(CASE WHEN Status = 'F' THEN 1 ELSE 0 END) AS Failed,
SUM(CASE WHEN Status = 'E' THEN 1 ELSE 0 END) AS Error
FROM MailDefinition

No, because the shape of the query (the fields it contains) has to be known. Only the data can change, and that is what you should be looking for. You can dynamically remove or hide labels based on 0 or null data in a column.

What I would do is take what you have, throw it into an unpivot, then remove all of the 0 records.
select
Type,
Sum
from
(
SELECT
SUM(CASE WHEN Status = 'R' THEN 1 ELSE 0 END) AS Ready,
SUM(CASE WHEN Status = 'P' THEN 1 ELSE 0 END) AS Processing,
SUM(CASE WHEN Status = 'C' THEN 1 ELSE 0 END) AS Complete,
SUM(CASE WHEN Status = 'F' THEN 1 ELSE 0 END) AS Failed,
SUM(CASE WHEN Status = 'E' THEN 1 ELSE 0 END) AS Error
FROM MailDefinition
) a
unpivot
(
Sum for Type in ([Ready],[Processing],[Complete],[Failed],[Error])
) u
where Sum>0
That does, of course, entail changing your chart some.

Related

Sql loop over unique elements of a column

I am trying to get data of rows into columns. This is my data before query.
This is my query.
SELECT
Date,
SUM(CASE WHEN (Terms="Art") THEN 1 ELSE 0 END) AS Art,
SUM(CASE WHEN (Terms="Action") THEN 1 ELSE 0 END) AS Action,
SUM(CASE WHEN (Terms="Board") THEN 1 ELSE 0 END) AS Board,
SUM(CASE WHEN (Terms="Puzzle") THEN 1 ELSE 0 END) AS Puzzle,
SUM(CASE WHEN (Terms="Adventure") THEN 1 ELSE 0 END) AS Adventure,
SUM(CASE WHEN (Terms="Others") THEN 1 ELSE 0 END) AS Others
FROM
__table__
GROUP BY
Date
After Query this is my data.
Which is fine and intended data. But problem is in query as you can see I have to explicitly write each term. I want to automate that using loop. Theoretical solution is to write subquery to get all unique terms and then loop over them. But I don't know how.

How to add columns from another table using a SELECT

I have a table named Action, which I want to add new columns to it.
The columns that I want to add are the result of this query :
SELECT DATE_AFFECTATION ,
SUM(CASE WHEN STATUT_Ticket = 'Clôturé' THEN 1 ELSE 0 END) AS TotalCloturé,
SUM(CASE WHEN STATUT_Ticket = 'En cours' THEN 1 ELSE 0 END) AS TotalEncours,
SUM(CASE WHEN STATUT_Ticket = 'Gelé' THEN 1 ELSE 0 END) AS TotalGelé,
SUM(CASE WHEN STATUT_Ticket = 'Hors délai' THEN 1 ELSE 0 END) AS TotalHorsdélai,
SUM(CASE WHEN STATUT_Ticket = 'Nouveau' THEN 1 ELSE 0 END) AS TotalNouveau,
SUM(Sum(CASE WHEN STATUT_Ticket = 'Clôturé' THEN 1 ELSE 0 END)) Over (ORDER BY DATE_AFFECTATION) AS cumTotalCloturé,
SUM(Sum(CASE WHEN STATUT_Ticket = 'En cours' THEN 1 ELSE 0 END)) Over (ORDER BY DATE_AFFECTATION) AS cumTotalEncours,
SUM(Sum(CASE WHEN STATUT_Ticket = 'Gelé' THEN 1 ELSE 0 END)) Over (ORDER BY DATE_AFFECTATION) AS cumTotalGelé,
SUM(Sum(CASE WHEN STATUT_Ticket = 'Hors délai' THEN 1 ELSE 0 END)) Over (ORDER BY DATE_AFFECTATION) AS cumTotalHorsdélai,
SUM(Sum(CASE WHEN STATUT_Ticket = 'Nouveau' THEN 1 ELSE 0 END)) Over (ORDER BY DATE_AFFECTATION) AS cumTotalNouveau
FROM DIM_Ticket
GROUP BY DATE_AFFECTATION
ORDER BY DATE_AFFECTATION
Is this possible?
This is too long for a comment.
If you want to add columns to an existing table, then the syntax is alter table. For instance:
alter table add column TotalCloturé int;
The default values are NULL or you can provide a constant default (such as 0 in this case).
You don't add columns with a query.
Hence, your question is quite unclear. Are you simply trying to assign values to existing columns? Do you just want a result set with these column values in addition to the columns in the original table? Do you need triggers (or some other mechanism) so the values remain synchronized?
Your query return more than one column.
You can't add a column and fill it in a single Query.

How do I change a constant value to a column header in SQL?

The SQL query:
select type,count(*), 'Active'
from file where removed = '0'
union all
select type,count(*), 'Removed'
from file where removed = '1'
gives:
TYPE COUNT ( * ) Constant value
A 24,168 Active
A 1 Removed
B 8,280 Active
B 1,263 Removed
However, how can I change the SQL to get:
TYPE Active Removed
A 24,168 1
B 8,280 1,263
Supplementary optional question: and what's the best way to include the following total?
TYPE Active Removed
A 24,168 1
B 8,280 1,263
Total 32,448 1,264
This is my best answer to the supplementary, please let me know if you see any flaws or improvements:
select
type,
sum(CASE WHEN removed = '0' THEN 1 ELSE 0 END) 'Active',
sum(CASE WHEN removed = '1' THEN 1 ELSE 0 END) 'Removed'
from file
Group by type
union all
select 'Total',
sum(CASE WHEN removed = '0' THEN 1 ELSE 0 END) 'Active',
sum(CASE WHEN removed = '1' THEN 1 ELSE 0 END) 'Removed'
from file
Thank you to everyone who commented or answered, your help is appreciated.
You can try:
select
type,
sum(CASE WHEN removed = '0' THEN 1 ELSE 0 END) 'Active',
sum(CASE WHEN removed = '1' THEN 1 ELSE 0 END) 'Removed'
from file
Group by type
Use case expressions to do conditional aggregation:
select type,
count(case when removed = '0' then 1 end) as "Active",
count(case when removed = '1' then 1 end) as "Removed"
from file
group by type
If there are many rows with other removed values than 0/1, and the column is indexed, you can throw in a
WHERE removed IN ('0','1')
to speed things up!
In order to get totals into the answer without union try:
select
coalesce(type, 'Totals') type,
sum(CASE WHEN removed = '0' THEN 1 ELSE 0 END) Active,
sum(CASE WHEN removed = '1' THEN 1 ELSE 0 END) Removed
from file
Group by rollup(type)
This works for v6.1 and later.

Avoiding a divide by zero error in a case statement

I am getting a divide by zero error in my script.
Can anyone please help.
I am trying to divide two records and one of them has zero in it. I dont want to lose the row, please advise.
select DATEPART(Year,Request_date) as "Year",
DATEPART(Month,Request_date) as "Month",
COUNT([MONTH_OF_SUSPENSION]) as "Request" ,
sum(case when [PAYMENT_<=24HRS] = 'Y' then 1 else 0 end) as "Paid in 24hrs",
COUNT([MONTH_OF_SUSPENSION])/sum(case when [PAYMENT_<=24HRS] = 'Y' then 1 else 0 end) as "Achieved"
FROM suspension_br
where REQUEST_STATUS = 'OTHERS'
GROUP BY DATEPART(Year,Request_date),DATEPART(Month,Request_date)
You can introduce a second case to check the result of the sum:
case
when sum(case when [PAYMENT_<=24HRS] = 'Y' then 1 else 0 end) > 0
then COUNT([MONTH_OF_SUSPENSION])/sum(case when [PAYMENT_<=24HRS] = 'Y' then 1 else 0 end)
else 0 /* a default value that makes sense to you */
end as "Achieved"
Looking at your code I could assume you are using MSSQL and therefore you could use nullif which returns null if two arguments are equal. So for example your code could look like :
COUNT([MONTH_OF_SUSPENSION])/nullif(sum(case when [PAYMENT_<=24HRS] = 'Y' then 1 else 0 end),0) as "Achieved"
What it does is if the value of the sum operator is equal 0 then the divisor is turn from zero into null and that will result in the entire equation to become null.
use another case statement to check the result of your sum
select DATEPART(Year,Request_date) as "Year",
DATEPART(Month,Request_date) as "Month",
COUNT([MONTH_OF_SUSPENSION]) as "Request" ,
sum(case
when [PAYMENT_<=24HRS] = 'Y' then 1
else 0
end) as "Paid in 24hrs",
case
when sum(case
when [PAYMENT_<=24HRS] = 'Y' then 1
else 0
end) = 0 then 'whatever you want in this case'
else COUNT([MONTH_OF_SUSPENSION])/sum(case
when [PAYMENT_<=24HRS] = 'Y' then 1
else 0
end) as "Achieved"
FROM suspension_br
where REQUEST_STATUS = 'OTHERS'
GROUP BY DATEPART(Year,Request_date),DATEPART(Month,Request_date)
although this is pretty nasty looking, so you could tidy it up a bit with a sub-select:
select
year,
month,
request,
PaidIn24hrs,
case
when PaidIn24hrs = 0 then 'whatever you want in this case'
else request/PaidIn24hrs
end as "Achieved"
from
(
select DATEPART(Year,Request_date) as "Year",
DATEPART(Month,Request_date) as "Month",
COUNT([MONTH_OF_SUSPENSION]) as "Request" ,
sum(case
when [PAYMENT_<=24HRS] = 'Y' then 1
else 0
end) as "PaidIn24hrs"
FROM suspension_br
where REQUEST_STATUS = 'OTHERS'
GROUP BY DATEPART(Year,Request_date),DATEPART(Month,Request_date)
)

select sum statement

I created this select statement I will convert to a view. I need help with this. I need to be able to add the total of Minority that = Yes and No show total on report pages.
select
ps.BidPackage_ID,
ps.Project_ID,
SUM (case ps.Minority when 'Yes' then 1 else 0 end) MinorityTotal,
SUM (case ps.Gender when 'Female' then 1 else 0 end) FemaleTotal,
SUM(case ps.Cleveland_Resident when 1 then 1 else 0 end) ClevelandResidents,
ps.SubContractor
from
PersonnelSummary ps
group by
ps.BidPackage_ID,
ps.Project_ID,
ps.SubContractor
You nearly have it:
...
SUM (case ps.Minority when 'Yes' then 1 else 0 end) AS MinorityYes,
SUM (case ps.Minority when 'No' then 1 else 0 end) AS MinorityNo,
COUNT(*) AS Total,
...
With the Total I'm assuming that every row should be counted. This is what you want if:
The only values that exist in the column are 'Yes' and 'No' or
Values different from 'Yes' and 'No' should also be counted in the total.
You're forcing us to guess what you want. You have a count of the people who said that they were in a minority; do you want a count of the people who said No? Or do you want a count of the number who said 'either "Yes" or "No"' and excluding those who gave 'decline to say' or simply no answer at all?
select
ps.BidPackage_ID,
ps.Project_ID,
SUM (case ps.Minority when 'Yes' then 1 else 0 end) MinorityTotalYes,
SUM (case ps.Minority when 'No' then 1 else 0 end) MinorityTotalNo,
SUM (case ps.Minority when 'Yes' then 1 when 'No' then 1 else 0 end)
AS StatedMinorityTotal,
SUM (case ps.Gender when 'Female' then 1 else 0 end) FemaleTotal,
SUM(case ps.Cleveland_Resident when 1 then 1 else 0 end) ClevelandResidents,
ps.SubContractor
from
PersonnelSummary ps
group by
ps.BidPackage_ID,
ps.Project_ID,
ps.SubContractor