Trigger MySql while using CONCAT inserting data is Null - mysql

This is the query i execute after insertation in some table in my database. Here i am getting rate_like_id and all other fields i also save them but when i use CONCAT and trying to save them as json it inserts NULL value via trigger.
Is this a wrong way to do this. Is ther any other way i can save this type of data via trigger mysql.
INSERT INTO `log_activity`(`visitor_id`,
`rating_like_id`,
`type`,
`response`,
`created_by`,
`created_date`)
VALUES (new.created_by,
new.rating_like_id,
CASE WHEN new.is_like = NULL THEN "Rating" ELSE "Like" END ,
-- Here is this column Should not be null but it is coming null when INSERTED
CONCAT(
'{"card_id":','"',new.card_id,'"',
',"card_type":','"',new.card_type,'"',
',"user_id":','"',new.user_id,'"',
',"is_like":','"',new.is_like,'"',
',"has_rated":','"',new.has_rated,'"',
',"rate":','"',new.rate,'"',
',"created_by":','"',new.created_by,'"',
',"created_date":','"',new.created_date,'"',
',"card_type":','"',new.card_type,'"','}'),
new.created_by,
new.created_date)
what is wrong with this .. all other fields are saved correctly only CONCAT field is not getting inserted properly.
Yes I am able to insert value like this
CONCAT(" hi "," how "," are "," you ", " ? ")
Is this problem because i am using "new.fieldName" inside CONCAT ... i see THIS question they are doing the same thing .. ofcource it is less complex compare to mine.

If you see comments and conversation between me and marcB.. you will get the answer...
Here i want to show what changes i made to my query to make it work.
marcB said :- Remember that sql null is contagious. if ANY of the fields you're concatting are themselves null, the ENTIRE result becomes null
so you can see my query in question.. i do not have checked for any value is it null or not. So i just had to add the null check.
INSERT INTO `log_activity`(`visitor_id`,
`rating_like_id`,
`type`,
`response`,
`created_by`,
`created_date`)
VALUES (new.created_by,
new.rating_like_id,
CASE WHEN new.is_like = NULL THEN "Rating" ELSE "Like" END,
CONCAT('{"card_id":',
'"',
IFNULL(new.card_id, ''),
'"',
',"card_type":',
'"',
IFNULL(new.card_type, ''),
'"',
',"user_id":',
'"',
IFNULL(new.user_id, ''),
'"',
',"is_like":',
'"',
IFNULL(new.is_like, ''),
'"',
',"has_rated":',
'"',
IFNULL(new.has_rated, ''),
'"',
',"rate":',
'"',
IFNULL(new.rate, ''),
'"',
',"created_by":',
'"',
IFNULL(new.created_by, ''),
'"',
',"created_date":',
'"',
IFNULL(new.created_date, ''),
'"',
',"card_type":',
'"',
IFNULL(new.card_type, ''),
'"',
'}'),
new.created_by,
new.created_date)
It checks for the null value of the field.

Related

Updating blank cells to NULL causes ALL cells to be NULL

I have a query that I'm trying to use to update only cells with empty strings to NULL. But instead, when I run this command ALL of the cells end up being NULL:
UPDATE table_name
SET InvoiceId=NULL,
LinkedAccountId=NULL,
RecordId=NULL,
ProductName=NULL,
RateId=NULL,
SubscriptionId=NULL,
PricingPlanId=NULL,
UsageType=NULL,
Operation=NULL,
AvailabilityZone=NULL,
ReservedInstance=NULL,
UsageStartDate=NULL,
UsageEndDate=NULL,
UsageQuantity=NULL,
BlendedRate=NULL,
UnBlendedRate=NULL,
ResourceId=NULL,
Engagement=NULL,
Name=NULL,
Owner=NULL,
Parent=NULL
WHERE InvoiceId=''
OR LinkedAccountId=''
OR RecordId=''
OR ProductName=''
OR RateId=''
OR SubscriptionId=''
OR PricingPlanId=''
OR UsageType=''
OR UsageEndDate=''
OR Operation=''
OR AvailabilityZone=''
OR ReservedInstance=''
OR UsageStartDate=''
OR UsageEndDate=''
OR UsageQuantity=''
OR BlendedRate=''
OR UnBlendedRate=''
OR ResourceId=''
OR Engagement=''
OR Name=''
OR Owner=''
OR Parent='';
What am I doing wrong?
You are setting ALL fields to NULL where any field = ''
You might need to write as many queries as fields you want to update.
I might be wrong, but I don't think this is possible to do in a single query
UPDATE table_name
SET InvoiceId = NULL
WHERE InvoiceId = ''
And this for every fields
The way to interpret your SQL query is kind of like this:
UPDATE table_name
SET
(all these fields to null)
WHERE
(if ANY Of these conditions is true)
I agree with Cid that it might be the safest to do 1 field per query at a time, but this is how you could write this in a single query:
UPDATE table_name SET
field1 = IF(field1='',NULL,field1),
field2 = IF(field2='',NULL,field2),
/* etc */
I think you're assuming that the terms in your WHERE clause have an implicit correlation with the assignments in your SET clause, so only some columns will be set, depending on which ones satisfy individual terms in the WHERE clause. This is not how SQL works.
What really happens is that the whole condition of the WHERE clause is evaluated to select which rows are affected. Then all the SET assignments are applied, so all columns will be changed on the rows that satisfy the whole WHERE clause condition.
To do what you want in one pass, you could do it this way:
UPDATE table_name
SET InvoiceId=NULLIF(InvoiceId, ''),
LinkedAccountId=NULLIF(LinkedAccountId, ''),
RecordId=NULLIF(RecordId, ''),
ProductName=NULLIF(ProductName, ''),
RateId=NULLIF(RateId, ''),
SubscriptionId=NULLIF(SubscriptionId, ''),
PricingPlanId=NULLIF(PricingPlanId, ''),
UsageType=NULLIF(UsageTYpe, ''),
Operation=NULLIF(Operation, ''),
AvailabilityZone=NULLIF(AvailabilityZone, ''),
ReservedInstance=NULLIF(ReservedInstance, ''),
UsageStartDate=NULLIF(UsageStartDate, ''),
UsageEndDate=NULLIF(UsageEndDate, ''),
UsageQuantity=NULLIF(UsageQuantity, ''),
BlendedRate=NULLIF(BlendedRate, ''),
UnBlendedRate=NULLIF(UnBlendedRate, ''),
ResourceId=NULLIF(ResourceId, ''),
Engagement=NULLIF(Engagement, ''),
Name=NULLIF(Name, ''),
Owner=NULLIF(Owner, ''),
Parent=NULLIF(Parent, '')
The NULLIF() function returns NULL if its two arguments are equal, otherwise it returns the first argument. So in the case that each column is not '' then it is a no-op, setting the column to its own original value.

Ho to strip and replace values in mysql

I have around 200,000 records of data with phone numbers, but the numbers are inconsistent.
for example, some may be 10 digits (missing a 0 at the beginning), some have spaces in there, some have a '-' in the middle and some begin with '+44' instead of 0.
Is there a way in mySQL to condition all these and cleanse the data in one query?
Without sample data and without an example output this is purely speculative and assuming you want the output in the format of 01234567891.
Use a combination of LENGTH, REPLACE' ANDLEFT` functions to resolve the 4 issues you highlighted:
Missing 0 at beggining.
Spaces in the string.
-'s in the string.
+44 rather than 0.
SELECT CASE WHEN LENGTH(REPLACE(REPLACE(numberfield, '-', ''), ' ', '')) = 10
THEN CONCAT('0', REPLACE(REPLACE(numberfield, '-', ''), ' ', ''))
WHEN LEFT(REPLACE(REPLACE(numberfield, '-', ''), ' ', ''), 3) = '+44'
THEN REPLACE(REPLACE(REPLACE(numberfield, '-', ''), ' ', ''), '+44', '0'
END AS Cleannumber
FROM yourtable
Assuming the phone number field is a string - the following should deal with the conditions you specified :
RIGHT( LPAD( REPLACE( REPLACE( REPLACE('phonenumber', '-', ''), '+44', ''), ' ', ''), 11, '0' ), 11 )
first any '-' are removed, then '+44' is removed, then spaces are removed, then 11 '0's are added to the start of the number, finally the rightmost 11 characters are taken.
So you would do an UPDATE query replacing the phonenumber column.

Getting empty result if there is 'null' value in CONCAT

I expected to get full name without middle initial if there is no middle name, but if column "M_NAME" is Null, the select statement returns empty. How can i solve this?
SELECT CONCAT(`Employee`.`F_NAME`, ' ', LEFT(`Employee`.`M_NAME`, 1), '. ', `Employee`.`L_NAME`) FROM `ccms`.`Employee` WHERE HR_ID = '223';
CONCAT returns NULL if any argument is null. You can solve this by making sure that no null argument is null by wrapping any nullable column in either IFNULL or COALESCE (the latter can take more than two arguments).
SELECT
CONCAT(
IFNULL(F_NAME, ''),
' ',
IFNULL(CONCAT(LEFT(M_NAME, 1), '. '), ''),
IFNULL(L_NAME, '')
)
FROM
ccms.Employee
WHERE
HR_ID = '223';
What this does is replace NULL column values with an empty string, which is probably your intent. Note that I updated the selection of M_NAME so that the period is only added if the value is not null by using this very behavior.
EDIT: You can use backticks and qualify column names if you want, but it's not necessary for this exact query.
Use COALESCE()
Returns the first non-NULL value in the list, or NULL if there are no non-NULL values.
SELECT CONCAT(`Employee`.`F_NAME`, ' ', COALESCE(LEFT(`Employee`.`M_NAME`, 1), ''), '. ', `Employee`.`L_NAME`) FROM `ccms`.`Employee` WHERE HR_ID = '223';
Use IFNULL().
Any place you have a possibly NULL field, wrap it with IFNULL(whatever, '') and then you'll get an empty string instead of a result-killing NULL.
another simple solution is use CONCAT_WS. It will work defenitely.
SELECT
CONCAT_WS(''
F_NAME,
'',
LEFT(M_NAME, 1),
L_NAME) FROM
ccms.Employee WHERE HR_ID = '223';

Conditional CONCAT with potentially NULL or empty values

In the below piece of code, I am creating an Address field by concatenating various parts of an address.
However, if for instance address2 was empty, the trailing , will still be concatenated into Address.
This means if all fields were empty, I end up with a result of ,,,,.
If address1 is "House Number" and everything else is empty, I end up with House Number,,,,.
CONCAT( COALESCE(address1,'') , ', ' ,
COALESCE(address2,'') , ', ' ,
COALESCE(address3,'') , ', ' ,
COALESCE(city,'') , ', ' ,
COALESCE(zip, '')
) AS Address,
Is there some way of conditionally placing the commas between address parts only if the content of an address part is not empty.
Such as something along the lines of (pseudo-code) IF(address1) is NULL use '' ELSE use ','
Thank you.
CONCAT_WS(', ',
IF(LENGTH(`address1`),`address1`,NULL),
IF(LENGTH(`address2`),`address2`,NULL),
IF(LENGTH(`address3`),`address3`,NULL),
IF(LENGTH(`city`),`city`,NULL),
IF(LENGTH(`zip`),`zip`,NULL)
)
Using CONCAT_WS as Mat says is a very good idea, but I thought I'd do it a different way, with messy IF() statements:
CONCAT( COALESCE(address1,''), IF(LENGTH(address1), ', ', ''),
COALESCE(address2,''), IF(LENGTH(address2), ', ', ''),
COALESCE(address3,''), IF(LENGTH(address3), ', ', ''),
COALESCE(city,''), IF(LENGTH(city), ', ', ''),
COALESCE(zip,''), IF(LENGTH(address1), ', ', ''),
) AS Address,
The IF()s check if the field has a length and if so returns a comma. Otherwise, it returns an empty string.
try with MAKE_SET
SELECT MAKE_SET(11111,`address1`,`address2`,`address3`,`city`,`zip`) AS Address
It will returns a string with all NOT NULL value separated by ,
CONCAT_WS(', ',
NULLIF(`address1`,''),
NULLIF(`address2`,''),
NULLIF(`address3`,''),
NULLIF(`city`,''),
NULLIF(`zip`,'')
)
CONCAT_WS combines non-NULL strings.
NULLIF writes NULL if left and right side are equals. In this case if values are equals an empty sting ''.

Convert a Negative Number with Parentheses to a Minus in MYSQL

I have a MYSQL database with Negative numbers that are enclosed in parenthesis
eg. (14,500) which is supposed to be -14500.
I am storing the numbers as varchar. I am trying to convert all the numbers to a double or float format and also format the negative numbers with a minus sign.
My code:
select case
when substr(gross_d,1,1) = '(' then
ltrim('(') and rtrim(')') *-1
else
(gross_d)
end gross_d_num
from buy;
convert(gross_d_num,Double);
The problem with my current method is all the negative numbers with the parenthesis are converted to zero. Is there a different method to get my result.
edit:
I also removed the *-1 to see if the Parenthesis is removed and I get a value of zero.
Something like
convert (
case
when gross_d LIKE '(%)' THEN CONCAT('-', REPLACE(REPLACE(gross_d, ')', ''), '(', ''))
else gross_d
end, decimal(19,6))
Here, you are trimming parenthesis only. This becomes zero when you multiply by -1
ltrim('(') and rtrim(')') *-1
CONVERT(
IF( gross_d LIKE '(%)'
,CONCAT( '-', SUBSTR( gross_d, 1, LENGTH( gross_d ) - 2 ) )
,gross_d )
,DECIMAL );
At our company we don't have control over currency formatting used by external parties uploading excel sheets. We currently use this to convert the currencies and add a case whenever something new shows up :
SET #netSale := '$ (154.00)';
SELECT CONVERT (
CASE
when #netSale LIKE '$ (%)' THEN CONCAT('-', REPLACE(REPLACE(REPLACE(#netSale, '$ ', ''), ')', ''), '(', ''))
when #netSale LIKE '(%)' THEN CONCAT('-', REPLACE(REPLACE(REPLACE(#netSale, '$ ', ''), ')', ''), '(', ''))
else REPLACE(REPLACE(#netSale,'$',''),',', '')
END, DECIMAL(10,2)
)
This deals with most formatting styles we have encountered and is especially useful when loading a converted CSV file to a table.