Is there a way to return all unique values within a given row - sql

I am working in Oracle SQL and I have a data set with these headers
In this data set card number is unique, however, the customer can have duplicates in their Suggestion fields. Rather than going through and writing case statements, is there a way to keep only the unique values within the given row?
Please note, some customers will be left with more "unique" suggestions than others
For example:
My goal would be for my final output to look like this
As I have mentioned, previously, I would just write case statements saying
SELECT DISTINCT CARD_NUMBER
,SUGGESTION_1
,CASE
WHEN SUGGESTION_2 != SUGGESTION_1
THEN SUGGESTION_2
WHEN SUGGESTION_3 != SUGGESTION_1
THEN SUGGESTION_3
WHEN SUGGESTION_4 != SUGGESTION_1
THEN SUGGESTION_4
WHEN SUGGESTION_5 != SUGGESTION_1
THEN SUGGESTION_5
END AS SUGGESTION_2
CASE
WHEN SUGGESTION_2 != SUGGESTION_1
AND SUGGESTION_3 != SUGGESTION_1
AND SUGGESTION_3 != SUGGESTION_2
THEN SUGGESTION_3
`
I would do this until all unique values are left, and there just has to be an easier way
Any help would be EXTREMELY appreciated, thank you!

You can use union all and conditional aggregation. Here is the idea that puts the results in a single column:
select card, listagg(suggestion, ', ') within group (order by which) as suggestions
from (select card, suggestion, min(which) as which
from ((select card, 1 as which, suggestion_1 as suggestion from t) union all
(select card, 2, suggestion_2 from t) union all
(select card, 3, suggestion_3 from t) union all
(select card, 4, suggestion_4 from t) union all
(select card, 5, suggestion_5 from t)
) t
group by card, suggestion
) t
group by card;
You can do something similar with conditional aggregation if you want the values in separate columns.

I would try to pivot the table to long, and then back to wide
Setup:
create table testtbl
(
CARD_NUMBER int
,SUGGESTION_1 varchar2(100)
,SUGGESTION_2 varchar2(100)
,SUGGESTION_3 varchar2(100)
,SUGGESTION_4 varchar2(100)
,SUGGESTION_5 varchar2(100)
);
insert into testtbl values (1234,'G11','G4','G3','G2','G6');
insert into testtbl values (5678,'G4','G6','G6','G11','G6');
insert into testtbl values (9101,'G1','G3','G11','G4','G11');
Then the Query itself, first the pivoting to long. Here I use a function just to return the numbers from 1 to 5 - this is instead of joining the table 5 times to itself, this way it should only pass through the test table once.
I then use the analytical functionrow_number to sort the unique values according to their first placement.
The second select uses MAX to pivot back to wide
with cte AS
(
SELECT
CARD_NUMBER
,MIN(n.column_value ) n
,CASE n.column_value
WHEN 1 THEN f.SUGGESTION_1
WHEN 2 THEN f.SUGGESTION_2
WHEN 3 THEN f.SUGGESTION_3
WHEN 4 THEN f.SUGGESTION_4
WHEN 5 THEN f.SUGGESTION_5
END Suggestion
,ROW_NUMBER() OVER (PARTITION BY f.CARD_NUMBER ORDER BY MIN(n.column_value)) rn
FROM testtbl f
CROSS JOIN table(sys.odcinumberlist(1,2,3,4,5)) n
GROUP BY f.CARD_NUMBER,CASE n.column_value
WHEN 1 THEN f.SUGGESTION_1
WHEN 2 THEN f.SUGGESTION_2
WHEN 3 THEN f.SUGGESTION_3
WHEN 4 THEN f.SUGGESTION_4
WHEN 5 THEN f.SUGGESTION_5
END
)
SELECT
CARD_NUMBER
,MAX(CASE WHEN rn=1 THEN Suggestion ELSE '' end)SUGGESTION_1
,MAX(CASE WHEN rn=2 THEN Suggestion ELSE '' end)SUGGESTION_2
,MAX(CASE WHEN rn=3 THEN Suggestion ELSE '' end)SUGGESTION_3
,MAX(CASE WHEN rn=4 THEN Suggestion ELSE '' end)SUGGESTION_4
,MAX(CASE WHEN rn=5 THEN Suggestion ELSE '' end)SUGGESTION_5
FROM cte
GROUP BY CARD_NUMBER
ORDER BY CARD_NUMBER

Related

Transpose row value to additional pre-defined field when value is less than specified value

I have a table that contains two identifying columns, a date, and a value. This value can be up to 100. What I want to do is where [ID] and [DATE] is the same across subsequent rows and the values are less than 100 (which also means [ID_SECONDARY] is always different), I want a query to place each one of these values in a column '[VALUE_1]...[VALUE_N]' along with the Value Description ([ID_SECONDARY]-->[VALUE_1_DESC]...[VALUE_N_DESC]). Ultimately each row should contain a unique [ID], [DATE], and an aggregation of the different [ID_SECONDARY] descriptions along with their values [VALUE_1]...[VALUE_N]. The number of unique [ID_SECONDARY] will not surpass 4, but could be from 1 to 4.
My initial inclination is to approach this using a cursor, but am hopeful there is a better alternative.
The first image is a sample of the information provided in the table, the second image is the output I'm looking for. Any help is greatly appreciated.
.
As far as I can tell this is different from the various dynamic pivot posts out there because the columns are independent of the secondary ID and are fully dependent on the VALUE column to determine if the value itself belongs in columns 1-4.
Try this
WITH a AS (
SELECT
ID
, [DATE]
, ID_SECONDARY
, VALUE
, ROW_NUMBER() OVER (PARTITION BY ID, DATE ORDER BY ID) AS RNUM
)
SELECT
a.ID
, a.[DATE]
, MAX (
CASE a.RNUM
WHEN 1 THEN a.VALUE
ELSE NULL
) AS VALUE_1
, MAX (
CASE a.RNUM
WHEN 1 THEN a.ID_SECONDARY
ELSE NULL
) AS VALUE_1_DESC
, MAX (
CASE a.RNUM
WHEN 2 THEN a.VALUE
ELSE NULL
) AS VALUE_2
, MAX (
CASE a.RNUM
WHEN 2 THEN a.ID_SECONDARY
ELSE NULL
) AS VALUE_2_DESC
, MAX (
CASE RNUM
WHEN 3 THEN a.VALUE
ELSE NULL
) AS VALUE_3
, MAX (
CASE RNUM
WHEN 3 THEN a.ID_SECONDARY
ELSE NULL
) AS VALUE_3_DESC
, MAX (
CASE RNUM
WHEN 4 THEN a.VALUE
ELSE NULL
) AS VALUE_4
, MAX (
CASE RNUM
WHEN 4 THEN a.ID_SECONDARY
ELSE NULL
) AS VALUE_4_DESC
FROM a
GROUP BY a.ID, a.[DATE]

Partial group by

QUERY:
select ws_path from workpaths where
(
(ws_path like '%R_%') or
(ws_path like '%PB_%' ) or
(ws_path like '%ST_%')
)
OUTPUT:
/x/eng/users/ST_3609843_ijti4689_3609843_1601272247
/x/eng/users/ST_3610020_zozt5229_3610020_1601282033
/x/eng/users/ST_3611181_zozt5229_3611181_1601282032
/x/eng/users/ST_3611226_zozt5229_3611226_1601282033
/x/eng/users-random/john/N_3582168_3551186_1601040805
/x/eng/users-random/james/N_3582619_3551186_1601041405
/x/eng/users-random/jimmy/N_3582791_3551186_1601042005
/x/eng/users/R_3606462_3606462_1601251334
/x/eng/users/R_3611775_3612090_1601290909
/x/eng/users/R_3612813_3613016_1601292252
Is there way to group partially by ST_, N_ and R_?
i.e. group by ws_path wont work at the moment for the obvious reason
I need to only look at the last item in the path (split by '/') and then the front part of splitting with '_'
You can use regexp_substr to get the patterns being searched for and then group by the number of such occurrences.
select regexp_substr(ws_path,'\/R_|\/PB_|\/ST_'), count(*)
from workpaths
group by regexp_substr(ws_path,'\/R_|\/PB_|\/ST_')
Regexp is a good solution but can be expensive. A simpler substring might be cheaper and faster:
CREATE TABLE tbl (field1 VARCHAR(100));
INSERT INTO dbo.tbl
( field1 )
VALUES
('/x/eng/users/ST_3609843_ijti4689_3609843_1601272247'),
('/x/eng/users/ST_3610020_zozt5229_3610020_1601282033'),
('/x/eng/users/ST_3611181_zozt5229_3611181_1601282032'),
('/x/eng/users/ST_3611226_zozt5229_3611226_1601282033'),
('/x/eng/users-random/john/N_3582168_3551186_1601040805'),
('/x/eng/users-random/james/N_3582619_3551186_1601041405'),
('/x/eng/users-random/jimmy/N_3582791_3551186_1601042005'),
('/x/eng/users/R_3606462_3606462_1601251334'),
('/x/eng/users/R_3611775_3612090_1601290909'),
('/x/eng/users/R_3612813_3613016_1601292252');
SELECT
COUNT(CASE WHEN field1 LIKE '%/ST_%' THEN 1 ELSE NULL END) AS 'st_count',
COUNT(CASE WHEN field1 LIKE '%/N_%' THEN 1 ELSE NULL END) AS 'n_count',
COUNT(CASE WHEN field1 LIKE '%/R_%' THEN 1 ELSE NULL END) AS 'r_count'
FROM dbo.tbl

SQL server mismach columns

I'm trying to write a query for SQL Server.
must sum two separate columns
if the column Debe is less than the column Haber should print "mismatch"
The explanation is :
There are two tables ContD and Cont with a common column ID
The table ContD has two important columns, Debe and Haber.
The table Cont has one important column, Importe
If the sum of Debe is not equal to the sum of Haber should report printing a message on another column.
If the final number Debe and Haber are equal, compared to the column Importe of the table Cont and print coincidence in another column
http://www.grupoalta.com/wp-content/uploads/queryconciliacion.png
This should do the trick:
Note: I have commented the script that you actually want to use, the uncommented script is a quick sample that I have made out of the screenshot you shared, but as #Horaciux said, please, include a sample the next time.
Note 2: I supposed that the id in your table Cont is the primary key or it is just Unique, meanwhile the id in the table contD is a foreign key or it just doesn't have the constraint of Uniqueness.
DECLARE #t1 AS TABLE (id NUMERIC,debe DECIMAL(18,2),haber DECIMAL(18,2))
DECLARE #t2 AS TABLE (id NUMERIC,importe DECIMAL(18,2))
INSERT INTO #t1
SELECT 10887,NULL,603.2 UNION ALL
SELECT 10887,83.2,NULL UNION ALL
SELECT 10887,520,NULL UNION ALL
SELECT 10888,NULL,21.344 UNION ALL
SELECT 10888,18.40,NULL UNION ALL
SELECT 10888,2.944,NULL
INSERT INTO #t2
SELECT 10887,603.2 UNION ALL
SELECT 10888,150
SELECT id
,SUM(debe) 'Debe'
,SUM(haber) 'Haber'
,(SELECT importe FROM #t2 where id=t1.id) 'Importe'
,CASE WHEN SUM(debe)=SUM(haber) THEN '' ELSE 'not equal' END 'Debe=Haber'
,CASE WHEN (SUM(debe)=SUM(haber) AND (SELECT importe FROM #t2 WHERE id=t1.id)=SUM(debe)) THEN 'Coincidence' ELSE '' END 'Debe=Haber=Importe'
FROM #t1 t1
GROUP BY id
/*
SELECT id
,SUM(debe) 'Debe'
,SUM(haber) 'Haber'
,(SELECT importe FROM #t2 where id=t1.id) 'Importe'
,CASE WHEN SUM(debe)<>SUM(haber) THEN 'not equal' ELSE '' END 'Debe=Haber'
,CASE WHEN (SUM(debe)=SUM(haber) AND (SELECT importe FROM cont WHERE id=t1.id)=SUM(debe)) THEN 'Coincidence' ELSE '' END 'Debe=Haber=Importe'
FROM contd t1
GROUP BY id
*/
here is an approach that does the comparison and returns one value, depending on the nature of the match. This uses a case statement:
select cd.id,
(case when cd.sumdebe <> cd.sumhaber then 'not equals'
when cd.sumdebe = c.importe then 'all same'
else 'mismatch'
end)
from (select id, sum(debe) as sumdebe, sum(haber) as sumhaber
from contd
group by id
) cd left outer join
cont c
on cd.id = c.id;

Is it possible to specify condition in Count()?

Is it possible to specify a condition in Count()? I would like to count only the rows that have, for example, "Manager" in the Position column.
I want to do it in the count statement, not using WHERE; I'm asking about it because I need to count both Managers and Other in the same SELECT (something like Count(Position = Manager), Count(Position = Other)) so WHERE is no use for me in this example.
If you can't just limit the query itself with a where clause, you can use the fact that the count aggregate only counts the non-null values:
select count(case Position when 'Manager' then 1 else null end)
from ...
You can also use the sum aggregate in a similar way:
select sum(case Position when 'Manager' then 1 else 0 end)
from ...
Assuming you do not want to restrict the rows that are returned because you are aggregating other values as well, you can do it like this:
select count(case when Position = 'Manager' then 1 else null end) as ManagerCount
from ...
Let's say within the same column you had values of Manager, Supervisor, and Team Lead, you could get the counts of each like this:
select count(case when Position = 'Manager' then 1 else null end) as ManagerCount,
count(case when Position = 'Supervisor' then 1 else null end) as SupervisorCount,
count(case when Position = 'Team Lead' then 1 else null end) as TeamLeadCount,
from ...
#Guffa 's answer is excellent, just point out that maybe is cleaner with an IF statement
select count(IIF(Position = 'Manager', 1, NULL)) as ManagerCount
from ...
Depends what you mean, but the other interpretation of the meaning is where you want to count rows with a certain value, but don't want to restrict the SELECT to JUST those rows...
You'd do it using SUM() with a clause in, like this instead of using COUNT():
e.g.
SELECT SUM(CASE WHEN Position = 'Manager' THEN 1 ELSE 0 END) AS ManagerCount,
SUM(CASE WHEN Position = 'CEO' THEN 1 ELSE 0 END) AS CEOCount
FROM SomeTable
If using Postgres or SQLite, you can use the Filter clause to improve readability:
SELECT
COUNT(1) FILTER (WHERE POSITION = 'Manager') AS ManagerCount,
COUNT(1) FILTER (WHERE POSITION = 'Other') AS OtherCount
FROM ...
BigQuery also has Countif - see the support across different SQL dialects for these features here:
https://modern-sql.com/feature/filter
You can also use the Pivot Keyword if you are using SQL 2005 or above
more info and from Technet
SELECT *
FROM #Users
PIVOT (
COUNT(Position)
FOR Position
IN (Manager, CEO, Employee)
) as p
Test Data Set
DECLARE #Users TABLE (Position VARCHAR(10))
INSERT INTO #Users (Position) VALUES('Manager')
INSERT INTO #Users (Position) VALUES('Manager')
INSERT INTO #Users (Position) VALUES('Manager')
INSERT INTO #Users (Position) VALUES('CEO')
INSERT INTO #Users (Position) VALUES('Employee')
INSERT INTO #Users (Position) VALUES('Employee')
INSERT INTO #Users (Position) VALUES('Employee')
INSERT INTO #Users (Position) VALUES('Employee')
INSERT INTO #Users (Position) VALUES('Employee')
INSERT INTO #Users (Position) VALUES('Employee')
Do you mean just this:
SELECT Count(*) FROM YourTable WHERE Position = 'Manager'
If so, then yup that works!
I know this is really old, but I like the NULLIF trick for such scenarios, and I found no downsides so far. Just see my copy&pasteable example, which is not very practical though, but demonstrates how to use it.
NULLIF might give you a small negative impact on performance, but I guess it should still be faster than subqueries.
DECLARE #tbl TABLE ( id [int] NOT NULL, field [varchar](50) NOT NULL)
INSERT INTO #tbl (id, field)
SELECT 1, 'Manager'
UNION SELECT 2, 'Manager'
UNION SELECT 3, 'Customer'
UNION SELECT 4, 'Boss'
UNION SELECT 5, 'Intern'
UNION SELECT 6, 'Customer'
UNION SELECT 7, 'Customer'
UNION SELECT 8, 'Wife'
UNION SELECT 9, 'Son'
SELECT * FROM #tbl
SELECT
COUNT(1) AS [total]
,COUNT(1) - COUNT(NULLIF([field], 'Manager')) AS [Managers]
,COUNT(NULLIF([field], 'Manager')) AS [NotManagers]
,(COUNT(1) - COUNT(NULLIF([field], 'Wife'))) + (COUNT(1) - COUNT(NULLIF([field], 'Son'))) AS [Family]
FROM #tbl
Comments appreciated :-)
Here is what I did to get a data set that included both the total and the number that met the criteria, within each shipping container. That let me answer the question "How many shipping containers have more than X% items over size 51"
select
Schedule,
PackageNum,
COUNT (UniqueID) as Total,
SUM (
case
when
Size > 51
then
1
else
0
end
) as NumOverSize
from
Inventory
where
customer like '%PEPSI%'
group by
Schedule, PackageNum
Note with PrestoDB SQL (from Facebook), there is a shortcut:
https://prestodb.io/docs/current/functions/aggregate.html
count_if(x) → bigint
Returns the number of TRUE input values. This
function is equivalent to count(CASE WHEN x THEN 1 END)
SELECT COUNT(*) FROM bla WHERE Position = 'Manager'
In MySQL, boolean expressions evaluate to 0 or 1, so the following aggregation works:
select sum(Position = 'Manager') as ManagerCount
from ...
I think you can use a simple WHERE clause to select only the count some record.

Counting null and non-null values in a single query

I have a table
create table us
(
a number
);
Now I have data like:
a
1
2
3
4
null
null
null
8
9
Now I need a single query to count null and not null values in column a
This works for Oracle and SQL Server (you might be able to get it to work on another RDBMS):
select sum(case when a is null then 1 else 0 end) count_nulls
, count(a) count_not_nulls
from us;
Or:
select count(*) - count(a), count(a) from us;
If I understood correctly you want to count all NULL and all NOT NULL in a column...
If that is correct:
SELECT count(*) FROM us WHERE a IS NULL
UNION ALL
SELECT count(*) FROM us WHERE a IS NOT NULL
Edited to have the full query, after reading the comments :]
SELECT COUNT(*), 'null_tally' AS narrative
FROM us
WHERE a IS NULL
UNION
SELECT COUNT(*), 'not_null_tally' AS narrative
FROM us
WHERE a IS NOT NULL;
Here is a quick and dirty version that works on Oracle :
select sum(case a when null then 1 else 0) "Null values",
sum(case a when null then 0 else 1) "Non-null values"
from us
for non nulls
select count(a)
from us
for nulls
select count(*)
from us
minus
select count(a)
from us
Hence
SELECT COUNT(A) NOT_NULLS
FROM US
UNION
SELECT COUNT(*) - COUNT(A) NULLS
FROM US
ought to do the job
Better in that the column titles come out correct.
SELECT COUNT(A) NOT_NULL, COUNT(*) - COUNT(A) NULLS
FROM US
In some testing on my system, it costs a full table scan.
As i understood your query, You just run this script and get Total Null,Total NotNull rows,
select count(*) - count(a) as 'Null', count(a) as 'Not Null' from us;
usually i use this trick
select sum(case when a is null then 0 else 1 end) as count_notnull,
sum(case when a is null then 1 else 0 end) as count_null
from tab
group by a
Just to provide yet another alternative, Postgres 9.4+ allows applying a FILTER to aggregates:
SELECT
COUNT(*) FILTER (WHERE a IS NULL) count_nulls,
COUNT(*) FILTER (WHERE a IS NOT NULL) count_not_nulls
FROM us;
SQLFiddle: http://sqlfiddle.com/#!17/80a24/5
This is little tricky. Assume the table has just one column, then the Count(1) and Count(*) will give different values.
set nocount on
declare #table1 table (empid int)
insert #table1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(NULL),(11),(12),(NULL),(13),(14);
select * from #table1
select COUNT(1) as "COUNT(1)" from #table1
select COUNT(empid) "Count(empid)" from #table1
Query Results
As you can see in the image, The first result shows the table has 16 rows. out of which two rows are NULL. So when we use Count(*) the query engine counts the number of rows, So we got count result as 16. But in case of Count(empid) it counted the non-NULL-values in the column empid. So we got the result as 14.
so whenever we are using COUNT(Column) make sure we take care of NULL values as shown below.
select COUNT(isnull(empid,1)) from #table1
will count both NULL and Non-NULL values.
Note: Same thing applies even when the table is made up of more than one column. Count(1) will give total number of rows irrespective of NULL/Non-NULL values. Only when the column values are counted using Count(Column) we need to take care of NULL values.
I had a similar issue: to count all distinct values, counting null values as 1, too. A simple count doesn't work in this case, as it does not take null values into account.
Here's a snippet that works on SQL and does not involve selection of new values.
Basically, once performed the distinct, also return the row number in a new column (n) using the row_number() function, then perform a count on that column:
SELECT COUNT(n)
FROM (
SELECT *, row_number() OVER (ORDER BY [MyColumn] ASC) n
FROM (
SELECT DISTINCT [MyColumn]
FROM [MyTable]
) items
) distinctItems
Try this..
SELECT CASE
WHEN a IS NULL THEN 'Null'
ELSE 'Not Null'
END a,
Count(1)
FROM us
GROUP BY CASE
WHEN a IS NULL THEN 'Null'
ELSE 'Not Null'
END
Here are two solutions:
Select count(columnname) as countofNotNulls, count(isnull(columnname,1))-count(columnname) AS Countofnulls from table name
OR
Select count(columnname) as countofNotNulls, count(*)-count(columnname) AS Countofnulls from table name
Try
SELECT
SUM(ISNULL(a)) AS all_null,
SUM(!ISNULL(a)) AS all_not_null
FROM us;
Simple!
If you're using MS Sql Server...
SELECT COUNT(0) AS 'Null_ColumnA_Records',
(
SELECT COUNT(0)
FROM your_table
WHERE ColumnA IS NOT NULL
) AS 'NOT_Null_ColumnA_Records'
FROM your_table
WHERE ColumnA IS NULL;
I don't recomend you doing this... but here you have it (in the same table as result)
use ISNULL embedded function.
All the answers are either wrong or extremely out of date.
The simple and correct way of doing this query is using COUNT_IF function.
SELECT
COUNT_IF(a IS NULL) AS nulls,
COUNT_IF(a IS NOT NULL) AS not_nulls
FROM
us
SELECT SUM(NULLs) AS 'NULLS', SUM(NOTNULLs) AS 'NOTNULLs' FROM
(select count(*) AS 'NULLs', 0 as 'NOTNULLs' FROM us WHERE a is null
UNION select 0 as 'NULLs', count(*) AS 'NOTNULLs' FROM us WHERE a is not null) AS x
It's fugly, but it will return a single record with 2 cols indicating the count of nulls vs non nulls.
This works in T-SQL. If you're just counting the number of something and you want to include the nulls, use COALESCE instead of case.
IF OBJECT_ID('tempdb..#us') IS NOT NULL
DROP TABLE #us
CREATE TABLE #us
(
a INT NULL
);
INSERT INTO #us VALUES (1),(2),(3),(4),(NULL),(NULL),(NULL),(8),(9)
SELECT * FROM #us
SELECT CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END AS 'NULL?',
COUNT(CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END) AS 'Count'
FROM #us
GROUP BY CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END
SELECT COALESCE(CAST(a AS NVARCHAR),'NULL') AS a,
COUNT(COALESCE(CAST(a AS NVARCHAR),'NULL')) AS 'Count'
FROM #us
GROUP BY COALESCE(CAST(a AS NVARCHAR),'NULL')
Building off of Alberto, I added the rollup.
SELECT [Narrative] = CASE
WHEN [Narrative] IS NULL THEN 'count_total' ELSE [Narrative] END
,[Count]=SUM([Count]) FROM (SELECT COUNT(*) [Count], 'count_nulls' AS [Narrative]
FROM [CrmDW].[CRM].[User]
WHERE [EmployeeID] IS NULL
UNION
SELECT COUNT(*), 'count_not_nulls ' AS narrative
FROM [CrmDW].[CRM].[User]
WHERE [EmployeeID] IS NOT NULL) S
GROUP BY [Narrative] WITH CUBE;
SELECT
ALL_VALUES
,COUNT(ALL_VALUES)
FROM(
SELECT
NVL2(A,'NOT NULL','NULL') AS ALL_VALUES
,NVL(A,0)
FROM US
)
GROUP BY ALL_VALUES
select count(isnull(NullableColumn,-1))
if its mysql, you can try something like this.
select
(select count(*) from TABLENAME WHERE a = 'null') as total_null,
(select count(*) from TABLENAME WHERE a != 'null') as total_not_null
FROM TABLENAME
Just in case you wanted it in a single record:
select
(select count(*) from tbl where colName is null) Nulls,
(select count(*) from tbl where colName is not null) NonNulls
;-)
for counting not null values
select count(*) from us where a is not null;
for counting null values
select count(*) from us where a is null;
I created the table in postgres 10 and both of the following worked:
select count(*) from us
and
select count(a is null) from us
In my case I wanted the "null distribution" amongst multiple columns:
SELECT
(CASE WHEN a IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS a_null,
(CASE WHEN b IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS b_null,
(CASE WHEN c IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS c_null,
...
count(*)
FROM us
GROUP BY 1, 2, 3,...
ORDER BY 1, 2, 3,...
As per the '...' it is easily extendable to more columns, as many as needed
Number of elements where a is null:
select count(a) from us where a is null;
Number of elements where a is not null:
select count(a) from us where a is not null;