Case When formula to COUNT on results tab - sql

On results tab of saved search, I would like to display a COUNT of Opportunities that do not have SLX in Title, Memo or Item Name. I'm using a transaction saved search.
I have tried a formula(numeric)results column and it returns incorrect results of one per grouped rep:
Formula(Numeric) Summary type: COUNT
CASE WHEN({title} = 'SLX') Or ({memo} = 'SLX') Or ({item.name} = 'SLX') THEN 1 ELSE 0 END
Counts one per Rep (grouped).

Hmmm . . . I think sum() is more appropriate:
SUM(CASE WHEN({title} = 'SLX') Or ({memo} = 'SLX') Or ({item.name} = 'SLX') THEN 1 ELSE 0 END)
Your expression is equivalent to COUNT(*), because COUNT() counts non-NULL values and all the values are either 1 or 0.

Related

What is the value being returned using "" in SQL WHERE filter?

In a dataset I am cleaning, according to the schema, there should only be two distinct values under the "usertype" column. Upon further analysis I discovered there is an empty third value accounting for 5828994 empty rows of the total dataset.
I tested to see if the third value would return NULL and it did not. As well as counted for Null and it returned a count of "0".
SELECT SUM(CASE WHEN usertype is null THEN 1 ELSE 0 END)
AS number_of_nulll
, COUNT(usertype) number_of_non_null
FROM dataset
I filtered to see if it would return an empty value but the results were - "There is no data to display"
WHERE usertype = " "
By chance I filtered WHERE usertype = "" and it returned the 5828994 rows as empty rows I was looking to isolate.
WHERE usertype = ""
My question is, what value did the "" filter return?
WHERE usertype = " "
Selects where the usertype is a single space - you get no results
WHERE usertype = ""
Selects where the usertype is blank (this is not the same as NULL). - This is where you get results.
Therefore, your table has strings that are blank, but they are not considered NULL, which of course could be confusing.
If you're manually loading this data yourself, I would check the google CLI for the parameter --null_marker, which should give you some options on how to handle this upon ingestion.
If you are stuck with it the way it is, you can get in the habit of using NULLIF() which can search for a condition and return NULL.
For example,
SELECT
SUM(CASE WHEN usertype is null THEN 1 ELSE 0 END) AS number_of_null,
SUM(CASE WHEN NULLIF(usertype,'') is null THEN 1 ELSE 0 END) AS number_of_null_or_blank,
COUNT(usertype) number_of_non_null
FROM dataset

How can I update if value is different or empty

I want to update my column if the vlaue is different from last value or its empty. I came up with this sql but it gives this error:
missing FROM-clause entry for table "box_per_pallet"
SQL:
UPDATE products AS p
SET box_per_pallet[0] = (CASE WHEN p.box_per_pallet.length = 0 THEN 0 ELSE p.box_per_pallet[0] END)
WHERE sku = 'A' AND store_id = 1
This is what I came up with based on your input. ARRAY_LENGTH takes the array and the dimension you want to check the length of as parameters. This missing from clause is because Postgres thinks that p.box_per_pallet is something other than an array and it can't find that anywhere in the query. You can't use the dot operator on arrays like p.box_per_pallet.length. It's like saying, "find the length field on table box_per_pallet in schema p".
UPDATE products
SET box_per_pallet[0] = CASE WHEN ARRAY_LENGTH(box_per_pallet, 1) = 0
OR box_per_pallet IS NULL
OR box_per_pallet[0] <> 0 -- your new value?
THEN 0
ELSE box_per_pallet[0]
END
WHERE sku = 'A'
AND store_id = 1
;
Here is a link to a dbfiddle showing the idea.

Using Max(boolean) in a case statement

I am made a temp table of accounts in a database with booleans that provide insight about the accounts. Some customers have multiple accounts so I am grouping them together and was trying to look at the MAX(Boolean) to set a status field.
My query kinda looks like:
with t as (Select lngCustomerNumber,
Case
When 'Criteria for being Active' Then 1
End as blnActive,
Case
When 'Criteria for unexpired' Then 1
End as blnUnexpired
From AccountTable)
Select t.CustomerNumber,
Case
When Max(t.blnActive) = 1
AND Max(t.blnUnexpired) = 1 Then 'Active/Unexpired'
When Max(t.blnActive) = 1
AND Max(t.blnUnexpired) = 0 Then 'Active/Expired'
When Max(t.blnActive) = 0
AND Max(t.blnUnexpired) = 1 Then 'Inactive/Unexpired'
When Max(t.blnActive) = 0
AND Max(t.blnUnexpired) = 0 Then 'Inactive/Expired'
End As strLicenseStatus
From T
Group By t.CustomerNumber
Anything where it checks if the Max(Boolean) = 1 will calc to True correctly, but if I do Max(Boolean) = 0 or Max(Boolean) <> 1 then it does not calc to True when it should.
I have tested by just looking at the grouped Temp Table with each boolean bringing back its Max() value and the ones that should be 0 are coming back as 0.
As a workaround, I have tried
Where t.CustomerNumber NOT IN (SELECT t2.CustomerNumber
FROM t t2
WHERE t2.blnUnexpired = 1
AND t2.CustomerNumber = t.CustomerNumber )
And that does give me the results that I am looking for but I have millions of rows coming back so it has been timing out after many hours, where the previous method was able to run in less than an hour.
I have some other data in my query, the one presented is a much smaller version used to highlight my issue.
Any recommendations on how I can make this work?
Thank you.
When you are defining your blnActive and blnUnexpired cases, you only have the "1" case defined, which means if it doesn't meet these criteria, it will be null. Try adding else 0 to each case:
with t as (Select lngCustomerNumber,
Case
When 'Criteria for being Active' Then 1
Else 0
End as blnActive,
Case
When 'Criteria for unexpired' Then 1
Else 0
End as blnUnexpired
From AccountTable)

SQL Creating a function to get the sum based on column name

Im trying to write a simple function that will allow me to get the sum based off the value of a column.
CREATE FUNCTION [GetSumOfColumnByCase](#column varchar(50), #case int)
RETURNS INT
AS
BEGIN
declare #return int
set #return = SUM(CASE WHEN #column = #case THEN 1 ELSE 0 END)
-- Return the result of the function
return #return
END
GO
I call this function like this:
SELECT HouseDescription,
[dbo].[GetSumOfColumnByCase]([HouseTypeId], 1) AS "houseType1",
[dbo].[GetSumOfColumnByCase]([HouseTypeId], 2) AS "houseType2"
Doing things this way forces me to GROUP BY both the houseDescription and the HouseTypeId columns but i just want to GROUP BY the housedescription.
If i do things this way:
SELECT HouseDescription,
SUM(CASE WHEN HouseTypeId = 1 THEN 1 ELSE 0 END) AS "houseType1",
SUM(CASE WHEN HouseTypeId = 2 THEN 1 ELSE 0 END) AS "houseType2"
Its fine, it doesnt force me to GROUP BY HouseTypeId.
Can anyone explain why this is?
When you are using a GROUP BY clause, every column needs to either be in the GROUP BY, or it needs to be aggregated.
In your second example, you are fulfilling these requirements - by placing the SUM around the function call. In your first example, since the function call itself isn't wrapped in an aggregation (SUM, MAX, MIN, etc.), you must place it in the GROUP BY clause in order to not trigger an error.
https://msdn.microsoft.com/en-us/library/ms177673.aspx
I agree with Gordon though, you may want to rethink your strategy for this.
You cannot do what you want with a function, because SQL Server does not support dynamic SQL (readily) in functions. And to handle any column, you would need dynamic SQL.
But, you don't need that anyway. If you want the sum on each row of the original data, you want window functions:
SELECT SUM(CASE WHEN HouseTypeId = 1 THEN 1 ELSE 0 END) OVER () AS houseType1,
SUM(CASE WHEN HouseTypeId = 2 THEN 1 ELSE 0 END) OVER () AS houseType2
. . .
Aggregation is not needed for this query.

SQL COUNT specific unit IF another field <> 0

I have a query that has a select statement that contains the following:
,COUNT(u.[Unit])
,up.[Number_Of_Stops]
I need to only count the units where number of stops <> 0. This has more details in the query so I can't just say WHERE number_of_stops <> 0. It has to be within the select statement.
Thanks
Try:
SUM(CASE WHEN up.[Number_Of_Stops] != 0 THEN 1 ELSE 0 END) AS countWhereNumStopsNotZero
(Edit: original answer said "COUNT" not "SUM")