Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting non-zero values in sql

Tags:

sql

sql-server

I am trying to count total number of times that each individual column is greater than zero, grouped by the driver name. Right now I have;

SELECT drivername
      , COUNT(over_rpm)      AS RPMViolations
      , COUNT(over_spd)      AS SpdViolations
      , COUNT(brake_events)  AS BrakeEvents
  FROM performxbydriverdata
 WHERE  over_rpm > 0
    OR over_spd > 0
    OR brake_events > 0
GROUP BY drivername

This gives me all of the non-zero values but I get a display as:

  • Bob Smith 62 62 62
  • Nathan Jones 65 65 65
  • etc.

I'm trying to get a count of non-zeros in each individual values.. each violation should be grouped separately.

like image 556
Jimmy Live Avatar asked May 27 '13 14:05

Jimmy Live


People also ask

Can you COUNT NULL values in SQL?

The SQL COUNT function excludes NULL values if you pass a specific column name. However, COUNT(*) includes rows with some NULL values. In other words, COUNT handles NULLs differently depending on what you pass it.

Does COUNT (*) ignore NULL values?

COUNT(*) returns the number of rows in the table or view. COUNT(*) counts all rows, including ones that contain duplicate column values or NULL values.

How do you COUNT values in SQL?

In SQL, you can make a database query and use the COUNT function to get the number of rows for a particular group in the table. Here is the basic syntax: SELECT COUNT(column_name) FROM table_name; COUNT(column_name) will not include NULL values as part of the count.


2 Answers

Use NULLIF to change zero to NULL, count ignores NULL

SELECT drivername,
     COUNT(NULLIF(over_rpm,0)) AS RPMViolations,
     COUNT(NULLIF(over_spd,0)) AS SpdViolations,
     COUNT(NULLIF(brake_events,0)) AS BrakeEvents
FROM performxbydriverdata
GROUP BY drivername;

You can probably remove the WHERE clause too with this group to improve performance
OR conditions often run badly because of matching a good index

Using HAVING (as per other answers) will remove any rows where all 3 aggregates are zero which may or may not be useful for you. You can add this if you want. Saying that, the WHERE implies that at least one row has non-zero values so you don't need both WHERE and HAVING clauses

like image 157
gbn Avatar answered Sep 29 '22 02:09

gbn


Putting filter predicate[s] inside of a Sum() function with a case statement is a useful trick anytime you need to count items based on some predicate condition.

Select DriverName,
    Sum(case When over_rpm > 0 Then 1 Else 0 End) OverRpm,
    Sum(case When over_spd > 0 Then 1 Else 0 End) OverSpeed,
    Sum(case When brake_events > 0 Then 1 Else 0 End) BrakeEvents,
    etc.
FROM performxbydriverdata
Group By DriverName
like image 22
Charles Bretana Avatar answered Sep 29 '22 01:09

Charles Bretana