Counting the number of NULLs in a SQL Server Column - sql

I have two queries like so:
SELECT MyId, MyColumn FROM MyTable WHERE MyColumn IS NULL;
SELECT count(MyColumn) as MyCount FROM MyTable WHERE MyColumn IS NULL;
The results I get are:
MyId MyColumn
10 NULL
Why is the count 0 always in the second query?

The COUNT() function ignores NULL values, and so the count in your second query will always be zero. Either count something else:
SELECT COUNT(*) AS MyCount
FROM MyTable
WHERE MyColumn IS NULL;
Or else count over the entire table using a CASE expression to explicitly count NULL values:
SELECT COUNT(CASE WHEN MyColumn IS NULL THEN 1 END) AS MyCount
FROM MyTable;

Count doesn't count null.
You need to do something like this, transform null to 1 then sum them:
SELECT SUM(CASE WHEN MyColumn IS NULL THEN 1 ELSE 0 END) AS count_nulls
FROM MyTable;

You can simply use count(1) rather than column name in the count function as it ignores null value which counting.
SELECT COUNT(1) AS MyCount
FROM MyTable
WHERE MyColumn IS NULL;

As noted, COUNT(SomeValue) just counts the number of non-nulls, so you actually needed COUNT(*).
But another way is to subtract the non-nulls from the total
SELECT COUNT(*) - COUNT(MyColumn) AS MyCount
FROM MyTable;
A WHERE is probably faster though, especially if you have an index on that column.

Related

Different WHERE clause depending on subquery result

I would like to SELECT WHERE column IS NULL or =value depending on result of subquery.
Here is an example incorrect solution that demonstrates the problem:
SELECT *
FROM table
WHERE column=(
SELECT (CASE WHEN COUNT(*) = COUNT(COLUMN) THEN MIN(column) END)
FROM table
)
When the subquery returns NULL the other query will return nothing because column=NULL is never true. How do I fix this?
(Subquery source: https://stackoverflow.com/a/51341498/7810882)
From your question. just add OR column IS NULL in where clause.
You will get the subquery condition or column IS NULL data.
SELECT *
FROM table
WHERE column= (
SELECT (CASE WHEN COUNT(*) = COUNT(COLUMN) THEN MIN(column) END)
FROM table
) OR column IS NULL
If you are only looking for one row, I would suggest:
select t.*
from table t
order by column nulls first
fetch first 1 row only;

Oracle SQL - convert select count(*) into zero or one

I'm using Oracle and I want to turn the result from a select count into a "binary" 0/1 value ... 0 = 0 ... non-zero = 1. From what I read online, in MS SQL, you can cast it to a "bit" but Oracle doesn't appear to support that.
Here's my simple example query (the real query is much more complex). I want MATCH_EXISTS to always be 0 or 1. Is this possible?
select count(*) as MATCH_EXISTS
from MY_TABLE
where MY_COLUMN is not null;
This should be fastest... get at most one row.
SELECT COUNT(*) AS MATCH_EXISTS
FROM MY_TABLE
WHERE MY_COLUMN IS NOT NULL
AND rownum <= 1;
If you use an exists clause this should be faster for large tables because Oracle doesn't need to scan the whole table. As soon as there is one row, it can stop retrieving it:
select count(*) as match_exists
from dual
where exists (select *
from my_table
where my_column is not null);
Don't do a count(). For performance, use exists:
select (case when exists (select 1 as MATCH_EXISTS
from MY_TABLE
where MY_COLUMN is not null
)
then 1 else 0
end)
from dual;
This can be significantly faster.
You can use CASE WHEN:
SELECT CASE WHEN MATCH_EXISTS = 0 THEN 0
ELSE 1
END AS MATCH_EXISTS
FROM (SELECT COUNT(*) AS MATCH_EXISTS
FROM MY_TABLE
WHERE MY_COLUMN IS NOT NULL) AS t;
EDIT:
SELECT CASE WHEN COUNT(*) = 0 THEN 0
ELSE 1
END as MATCH_EXISTS
FROM MY_TABLE
WHERE MY_COLUMN IS NOT NULL;

Using a value from one query in second query sql

SELECT AS, COUNT(*)
FROM Table1
HAVING COUNT(AS)>1
group BY AS;
This produces the result
AS COUNT
5 2
I then want to use the AS value in another query and only output the end result. Is this possible.i was thinking something like.
SELECT *
FROM
TABLE 2
Where AS =(
SELECT AS, COUNT(*)
FROM Table1
HAVING COUNT(AS)>1
group BY AS;
);
This is called a subquery. To be safe, you would use in instead of = (and as is a bad name for a column, because it is a SQL key word):
SELECT *
FROM TABLE2
WHERE col IN (SELECT col
FROM Table1
GROUP BY col
HAVING COUNT(col) > 1
);
Your first query is also incorrect, because the having clause goes after the group by.
You could use a subquery with the in operator:
SELECT *
FROM table2
WHERE AS IN (SELECT AS
FROM table1
GROUP BY AS
HAVING COUNT(*) > 1)

Group by is null or not?

I want to count how many records in Firebird database have timestamp field null or not null. How to do it?
Something like this:
select RECORD_TYPE, count(*), (MY_TIMESTAMP IS NULL) from MY_TABLE
group by RECORD_TYPE, (MY_TIMESTAMP IS NULL)
I'm using Firebird 2.5
You can output a single record with two columns,
SELECT COUNT(MY_TIMESTAMP) AS TOTAL_NOTNULL,
COUNT(CASE WHEN MY_TIMESTAMP IS NULL THEN 1 END) TOTAL_NULL
FROM MY_TABLE

sql restricted count query

I'm not certain how to structure a SQL query to return the number of rows where a column equals certain values.
For instance,
In table myTable, how can I return the count of all the rows where myColumn = "xyz" and where myColumn = "abc"? Is this possible with a single query?
To clarify, say there are 10 rows where myColumn = "xyx" and 7 rows where myColumn = "abc", the query would return something like:
firstCountResult: 10
secondCountResult: 7
How about?:
SELECT
COUNT(*),
myColumn
FROM myTable
WHERE myColumn IN ('xyz', 'abc')
GROUP BY myColumn
This approach also works with other aggregate functions like MIN, MAX, AVG, SUM... You get the aggregate result per the grouped column's value versus across all rows.
--min myDate per myColumn value
SELECT
MIN(myDate),
myColumn
FROM myTable
WHERE myColumn IN ('xyz', 'abc')
GROUP BY myColumn
--sum of myNumericCol per myColumn value
SELECT
SUM(myNumericCol),
myColumn
FROM myTable
WHERE myColumn IN ('xyz', 'abc')
GROUP BY myColumn
You want to group the count by mycolumn so you do this
select
myColumn, count(*)
from
myTable
where
myColumn in ('xyz','abc')
group by
myColumn