Count() Specifying Uncounted Value? - sql

Using Microsoft SQL Server, if you use COUNT(column name) it returns the number of rows in that column which have a non-null value (i.e., it counts the rows, ignoring nulls).
Is there any way to do something similar, but allowing you to tell it which values to ignore? For example, if I wanted to count all the rows in a table which have a value which is NOT 1, I could do something like COUNTNOT(column name,1). That would count all the rows in the specified column which have a value NOT 1.

You may use conditional aggregation:
SELECT COUNT(CASE WHEN some_val <> 1 THEN 1 END) AS cnt
FROM yourTable;
The above logic is that COUNT will count one whenever some value is not equal to 1. Otherwise, it falls on the ELSE conditional, which if not present defaults to the value NULL. Since NULL is not counted, any value other than 1 would contribute zero to the count.

Why not put what you want to exclude in a WHERE clause?
SELECT COUNT(some_val) AS cnt
FROM yourTable
WHERE some_val <> 1

You need to be careful about NULL values. I would recommend:
select sum(case when column in (<values to ignore>) then 0 else 1 end)
This will count NULL values as not in the list (even if NULL is in the list). To ignore NULL values (as well), switch the logic to:
select sum(case when column not in (<values to ignore>) then 1 else 0 end)
and be sure NULL is not in the list.

Related

T-SQL COUNT(*) counts NULLS but I don't want to count NULLS in row count

I have a scenario where I'm trying not to count a row where it has a zero, blank or NULL. But I'm not sure how to. I have used ISNULL to replace it with blank but the result shows zero. I don't want zero because it messes up my averages etc. The screen shot below should show 17 in the bottom as total but it's showing 18 because it's counting the null as row count. This null row has an N/A as a value in the data set but my count counts it as a row. I'm using count() because I have many other columns so I can not change the count(). Any ideas on how to show the total as 17 instead of 18?
Thank you
Some SQL implementations (I think this is also proper ANSI standard but don't know that for sure) exhibit a different behaviour for COUNT(*) VS COUNT(field).
The former will include NULLs, the latter will exclude them.
you can use SUM like this
SELECT SUM(CASE WHEN ISNULL(testeq4,'') <> '' THEN 1 ELSE 0 end)
FROM YourTable
Try this:
SELECT SUM(CASE WHEN ISNULL(TestQ4,0)=0 THEN 0 ELSE 1 END)

How to set flag based on values in previous columns in same table ? (Oracle)

I'm creating a new table and carrying over several columns from a previous table. One of the new fields that I need to create is a flag that will have values 0 or 1 and value needs to be determined based on 6 previous fields in the table.
The 6 previous columns have preexisting values of 0 or 1 stored for each one. This new field needs to check whether any of the 6 columns have 1 and if so set the flag to 0. If there is 0 in all 6 fields then set itself to 1.
Hopefully this makes sense. How can I get this done in oracle? I assume a case statement and some sort of forloop?
You can use greatest() function: GREATEST
create table t_new
as
select
case when greatest(c1,c2,c3,c4,c5,c6)=1 -- at least one of them contains 1
then 0
else 1
end c_new
from t_old;
Or even shorter:
create table t_new
as
select
1-greatest(c1,c2,c3,c4,c5,c6) as c_new
from t_old;
In case of greatest = 1, (1-1)=0, otherwise (1-0)=1
You can use a virtual column with a case expression; something like:
flag number generated always as (
case when val_1 + val_2 + val_3 + val_4 + val_5 + val_6 = 0 then 1 else 0 end
) virtual
db<>fiddle
or the same thing with greatest() as #Sayan suggested.
Using a virtual column means the flag will be right for newly-inserted rows, and if any of the other values are updated; you won't have to recalculate or update the flag column manually.
I've assumed the other six columns can't be null and are constrained to only be 0 or 1, as the question suggests. If they can be null you can add nvl() or coalesce() to each term in the calculation.

Count number of + and - values based on another column

I am trying to get a simple count of all the negative and positive values of a specific column on my database. I want to be able to count these values based on another column. What would be the best way to go about handling this problem.
enter image description here
Something like this:
SELECT
SUM(CASE WHEN column > 0 THEN 1 ELSE 0 END) as count_positive,
SUM(CASE WHEN column < 0 THEN 1 ELSE 0 END) as count_negative
FROM
table
You must put the column name, table name, and decide whether 0 is positive, negative or excluded (my choice)

Selective Summation inside the case statement

I am using sum function inside case statement. I want to do selective summation of rows.
case when
type in ('A','B')
then nvl(SUM(Amount_1),Amount)
else Amount
Two columns are there Amount and Amount_1 and for the Amount_1 column, I want to remove few rows based on some condition C1. For e.g. If I have 10 rows that have type in A and based on condition C1 I am getting only 8 rows then I want to sum Amount_1 column on the basis of 8 rows only.
I think you have the basic logic understood correctly, but your syntax is a bit off. You should be using the CASE expression inside the SUM() function, not the other way around.
SELECT type,
SUM(CASE WHEN type IN ('A', 'B')
THEN COALESCE(Amount_1, Amount) ELSE Amount END) AS type_sum -- ELSE 0 ?
FROM yourTable
This will compute the sum of COALESCE(Amount_1, Amount) for those records where the type is either A or B, otherwise it will use Amount in the sum. If you intended to not count non-matching records at all, then modify my query by using ELSE 0 in the CASE expression.

If field is empty, then 10 postgreSQL

I am trying to count price of all books. I need to make sure that if field is empty (it is NULL), then Book's value is 10. I have tried this:
SUM(CASE WHEN Value = NULL THEN 10 ELSE Value END) as main_value
But this doesn't do anything. It counts the sum fine, but when it finds empty field (null), it does not use value 10 in calculations.
What am I doing wrong?
If you just want to treat NULLs as 10s then COALESCE will do the trick:
The COALESCE function returns the first of its arguments that is not null. Null is returned only if all arguments are null.
So you could:
sum(coalesce(Value, 10))
To compare with null you need to use is null:
SUM(CASE WHEN Value is NULL THEN 10 ELSE Value END) as main_value