Count empty text fields in CASE sentence in MySQL - mysql

My column contains categories A, B, C or "empty" ( which means the record is not categorized).
I want to show the total number of A's, B's and C's and the total number of records "Not categorized", and have tried the query below.
It does not work, however. It shows the correct number of A, B and C's but not the number of not categorized.
SELECT count(*) AS Quantity,
CASE
WHEN cf_ab_contacts.col_621 = '' THEN "Uncategorized"
ELSE cf_ab_contacts.col_621
END AS `Category`
FROM ...
WHERE ...
GROUP BY `cf_ab_contacts`.`col_621`;
Thanks for all help.

I'm really sorry - but the query did work as intended - there was an error in my WHERE section which excluded empty columns.
Thanks to Ankit for your patience.
I'm not sure if I can delete this thread - I should never have posted it in the first place.

Considering By Empty you mean NULL not a single space value, You have to test the condition with IS NULL predicate -
SELECT count(*) AS Quantity,
CASE
WHEN cf_ab_contacts.col_621 IS NULL THEN "Uncategorized"
ELSE cf_ab_contacts.col_621
END AS `Category`
FROM ...
WHERE ...
GROUP BY CASE
WHEN cf_ab_contacts.col_621 IS NULL THEN "Uncategorized"
ELSE cf_ab_contacts.col_621
END;

Related

MYSQL - COUNT() NULL Values

This has been racking my head. I've scoured the internet (including this place) and can't find a solution. So as a last resort I was hoping the good people of this forum might be able to help me out.
I have two tables:
TableA
Order_detailsID
OrderID
TitleID
Return_date
TableB
TitleID
Title_name
Quantity_in_stock
And would like to run a query that shows the remaining 'Quantity_in_stock'.
If the 'Return_date' is set to NULL then it means the item is currently out -- so I have been trying to use the count() function for the NULL values and subtract it from the 'Quantity_in_stock'.
This is the script I have so far:
DELIMITER //
CREATE PROCEDURE InStock()
BEGIN
Select TableB.TitleID,
TableB.Title_name,
TableB.Quantity_in_stock AS 'Total_Stock',
COUNT(TableA.return_date IS NULL) AS 'Rented_Out',
TableB.Quantity_in_stock - COUNT(TableA.return_date IS NULL) AS 'Remaining Stock'
From TableB
LEFT JOIN TableA
ON TableA.TitleID = TableB.TitleID
GROUP BY TableB.TitleID;
END//
This works if there is one of more of the TitleIDs at NULL, however if there are no values at NULL, then the Count() is still returning a value of 1 when it should be 0.
What am I doing wrong?
Instead of:
COUNT(TableA.return_date IS NULL)
use this:
SUM(CASE
WHEN TableA.TitleID IS NULL THEN 0
WHEN TableA.return_date IS NOT NULL THEN 0
ELSE 1
END)
The problem with the TableA.return_date IS NULL predicate is that it's true in two completely different situations:
When there is no matching record in TableA
When there is a matching record but TableA.return_date value of this exact record is NULL.
Using the CASE expression you can differentiate between these two cases.
I will like to mention a simple concept here, just keep counting the rows when that particular column is null.
select count(*) from table_name where column_name is null

Spark sql: query with case and thousands of columns

I had a table with two thousands columns. i need to modify few columns data based on flag column.
tableSchemaRDD.registerAsTable("customer")
var results = sqlContext.sql("select *,case when flag1 = 'A' then null else charges end as charges, flag2 = 'B' then null then else stax end as stax from customer")
flag1,flag2, charges,stax are the columns from my table. the above code will give extra two coumns along with original columns. How can i get all columns with modified columns (charges,stax) based on flag columns.
Don't use asterisk ( * ), actually asterisk tells you have to bring all columns, after that you are using the two cases which are responsible for two new columns. You just have to remove asterisk ( * ) and place the column names comma separated without those column names which you are going to modify. In this way those two old columns will not be shown.
If you are using Spark 1.3 then its very easy for DataFrame, like
val columsNames = df.schema.fieldNames
.filter(fieldName => {
!fieldName.equals("charges") && !fieldName.equals("stax")
}).mkString(",")
Don't exactly remember that there are methods/properties in SchemaRDD or not.
EDITED:
Just understand the issue, asterisk tells bring all old columns, then you are using two new cases (two new columns.) also, where in your scenario you have to specify columns with their names without charges and stax, as these are your new columns, those will be populated by cases.
Suppose you have a table customer which has 4 columns, id name charges stax and you write the query like you are writing
select *,case when flag1 = 'A' then null else charges end as charges, flag2 = 'B' then null then else stax end as stax from customer
This will give you 6 columns, 4 for asterisk ( * ) as there are four columns in the table. and 2 for your cases. Instead of asterisk ( * ), you have to query like
select id , name ,case when flag1 = 'A' then null else charges end as charges, flag2 = 'B' then null then else stax end as stax from customer
This will result in 4 columns, id, name as they are (OLD). Stax and Charges (new) result of your cases.
Hopefully this will help.

Trying to Order DB Column Alphabetically using CASE

I have a database table that contains a number of fields that have a value of NULL for a specific column called category.
Currently I am executing this statement that returns a list of all the entries with NULL appearing at the end. However, for some reason it is not sorting them alphabetically and I'm wondering If someone can help me?
This is my script:
SELECT c.* FROM `directorycolumn` c
WHERE `c`.`directorycompany_id` = 740
ORDER BY CASE WHEN `category` IS NULL THEN 0 ELSE 1 END DESC
This outputs The category column with NULL values at the end but not in alphabetical order. I.e The first entry category begins with a T...but I have categories beginning with A.
Any help is much appreciated.
Just add a second Order By clause:
SELECT c.* FROM `directorycolumn` c
WHERE `c`.`directorycompany_id` = 740
ORDER BY CASE WHEN `category` IS NULL THEN 0 ELSE 1 END DESC, `category` ASC

I need to compare two rows of data for duplicate

I need to compare two rows of data for duplicate, if the consecutive rows are the same activityID I need to notate one is in error. This code is not working as I wish
My code is not testing correctly.
SELECT
CASE
WHEN activityId = activityId +1 THEN activityId = 'error'
ELSE activityId = activityId
END AS sortOrder,recordId,
activityId,
started,
completed,
userId
FROM log1644
You can not access the next or previous row like that. To be exact, there actually is not really a next or previous row, meaning that in a database data has no specific order when you don't specify it. As long as you don't have an ORDER BY one_or_multiple_columns in your query, the result you get back might get displayed in another order each time you issue your query.
That said, you have two possibilities:
join the table to itself
use variables
Joining the table to itself would work something like this
SELECT * FROM table alias_a
INNER JOIN table alias_b ON a.id = b.id + 1
Then a CASE WHEN a.whatever = b.whatever THEN 'error' ELSE 'cool' END would work, but this can become ugly pretty quickly, for example when the next id is not +1 but sometimes +2 because you deleted a row sometime or other causes. Or performancewise this can be bad, anyway...
I prefer using variables for cases like this.
SELECT
yt.*,
CASE WHEN #prevID = id THEN 'oops, same id as row before' ELSE 'another_id' END AS is_it_different,
#prevID := id
FROM your_table yt,
(SELECT #prevID := 0) table_alias__variable_initialization
ORDER BY id, another_column_determining_the_order_of_ids
As mentioned earlier, the ORDER BY is important here.
In the CASE WHEN ... the variable #prevID still has the value of the previous row. In the next line of the statement, the value of the current row gets assigned to the variable.

SQL server: where clause for optional fields

Track Id is optional field in my application.
Case 1: If I pass valid track id, it should return the respective rows.
Case 2: If invalid track id is passed, no rows should be returned.
Case 3: If no track id passed, all rows should be returned
DECLARE #transaction_ID INT
SELECT #transaction_ID = Transaction_ID FROM myTable WHERE TRACK_ID= #Track_Id
My where condition is:
WHERE (#transaction_ID IS NULL OR myTable.Transaction_ID = #transaction_ID)
AND (amount<>0)
with the above condition 1 and 3 cases are working fine. but 2nd case got failed. When I passed invalid track id, all rows are getting returned. Please correct the query to handle the case 2. Thanks in advance.
Just continue to query #Track_ID as well:
WHERE (
(#transaction_ID IS NULL AND #Track_Id IS NULL) OR
myTable.Transaction_ID = #transaction_ID)
AND (amount<>0)
(The only situation where you want a NULL #Transaction_ID to make this WHERE clause succeed is case 3. In Case 2, a non-null #Track_Id was passed but #Transaction_ID will be NULL because no rows were returned, so that's the situation we're trying to deal with)
Try something like this
Where 1=(Case when #TrackId = 1 Or TRACK_ID= #Track_Id then 1 else 0 end )
When you want all the data then pass 1 ,
When want data as per TrackID pass #trackID value and
when you dont wnat the condition to be applied pass null