I am currently working on a import and need to build a comma delimited string based on the values a table row. Iam able to do it this way but want to know if i can optimize this.
If((Select planValue from #tempTable) = 'Yes')
Begin
SET #ltValue='1'
END
If((Select planValue1 from #tempTable) = 'Yes')
Begin
IF(LEN(#ltValue) > 0)
BEGIN
SET #ltValue=#ltValue+',2'
END
ELSE
BEGIN
SET #ltValue='2'
END
END
If((Select planValue2 from #tempTable) = 'Yes')
Begin
IF(LEN(#ltValue) > 0)
BEGIN
SET #ltValue=#ltValue+',3'
END
ELSE
BEGIN
SET #ltValue='3'
END
END
An issue with your provided solution is if there are more than one row in the temp table. Here is an option that creates the string within a select.
DECLARE #tmpTable TABLE (
planValue varchar(5),
planValue1 varchar(5),
planValue2 varchar(5)
)
insert #tmpTable (planValue, planValue1, PlanValue2) VALUES ('Yes', 'Yes', 'No')
insert #tmpTable (planValue, planValue1, PlanValue2) VALUES ('Yes', 'No', 'No')
INSERT #tmpTable (planValue, planValue1, PlanValue2) VALUES ('No', 'Yes', 'Yes')
INSERT #tmpTable (planValue, planValue1, PlanValue2) VALUES ('No', 'No', 'Yes')
INSERT #tmpTable (planValue, planValue1, PlanValue2) VALUES ('Yes', 'Yes', 'Yes')
select REPLACE(REPLACE(CASE WHEN planValue = 'Yes' THEN '1|' ELSE '' END +
CASE WHEN planValue1 = 'Yes' THEN '|2|' ELSE '' END +
CASE WHEN planValue2 = 'Yes' THEN '|3|' ELSE '' END, '||', ','), '|', '') [ResultData]
FROM #tmpTable
OUTPUT
ResultData
1,2
1
2,3
3
1,2,3
The case statements add in the necessary values with a unique delimiter. The inner replace finds two consecutive delimiters and changes it to a comma. The last outer replace finds a single delimiter and removes it.
Related
I have a table data with combination of Integer and strings. Like this
CREATE TABLE EMPLOYEE (
empId INTEGER,
name TEXT NOT NULL,
email TEXT NOT NULL,
phone TEXT NOT NULL
);
INSERT INTO EMPLOYEE VALUES (12345, 'Clark Duff', 'Sales#yahoo.com',9001234567);
INSERT INTO EMPLOYEE VALUES (22245, 'Dave Johnson', 'Accounting#gmail.com',9000123456);
INSERT INTO EMPLOYEE VALUES (55456, 'Ava evelene', 'Sales_Marketing#gmail.com',9000012345);
But I'm looking for a common function in MYSQL to check the condition whether it is a special character or integer or string. Below syntax will mask the data:
If it is an integer then this condition needs to execute:
concat(SUBSTRING(phone,1,3) , '*****' , SUBSTRING(phone,7,4)) phone
If it is a special character (#) then this condition needs to execute:
CONCAT(LEFT(UUID(), 8), '#', SUBSTRING_INDEX(`Mail`, '#', -1)) as Mail
ELSE string then other script
seem you are looking for case statement applied to like condition for # char or cast to usingned for chekc a valid integer number
select case
when email like '%#%' then CONCAT(LEFT(UUID(), 8), '#', SUBSTRING_INDEX(`Mail`, '#', -1))
when cast(phone AS UNSIGNED) != 0 THEN concat(SUBSTRING(phone,1,3) , '*****' , SUBSTRING(phone,7,4))
else 'not managed'
end
One UDF to mask them.
CREATE FUNCTION fnMaskUserInfo (
input TEXT
)
RETURNS TEXT
DETERMINISTIC
BEGIN
IF input LIKE '%_#_%._%'
THEN
RETURN CONCAT(RIGHT(SHA1(input),8),'#',SUBSTRING_INDEX(input,'#',-1));
END IF;
IF input REGEXP '^[0-9]{7,10}$'
THEN
RETURN CONCAT(SUBSTRING(input,1,3),'*****',SUBSTRING(input,7,4));
END IF;
RETURN input;
END
SELECT empId
, fnMaskUserInfo(Name) AS Name
, fnMaskUserInfo(email) AS email
, fnMaskUserInfo(phone) AS phone
FROM EMPLOYEE
empId
Name
email
phone
12345
Clark Duff
1beb980f#yahoo.com
900*****4567
22245
Dave Johnson
1dadfff9#gmail.com
900*****3456
55456
Ava evelene
3a0768e7#gmail.com
900*****2345
Demo on db<>fiddle here
Here is an example stored function. Is this what you mean?
CREATE FUNCTION `someFunc`(
input VARCHAR(255)
)
RETURNS VARCHAR(255)
NOT DETERMINISTIC
BEGIN
IF input LIKE '%#%' THEN
RETURN CONCAT(LEFT(UUID(), 8), '#', SUBSTRING_INDEX(input, '#', -1));
ELSEIF input REGEXP '^[0-9 ]{7,10}$' THEN
RETURN CONCAT(SUBSTRING(input, 1, 3) , '*****' , SUBSTRING(input, 7, 4));
ELSE
RETURN input;
END IF;
END
You may want to use LEFT(MD5(input), 8) instead of LEFT(UUID(), 8) so that the function can be declared as deterministic.
CREATE FUNCTION `someFunc`(
input VARCHAR(255)
)
RETURNS VARCHAR(255)
DETERMINISTIC
BEGIN
IF input LIKE '%#%' THEN
RETURN CONCAT(LEFT(MD5(input), 8), '#', SUBSTRING_INDEX(input, '#', -1));
ELSEIF input REGEXP '^[0-9 ]{7,10}$' THEN
RETURN CONCAT(SUBSTRING(input, 1, 3) , '*****' , SUBSTRING(input, 7, 4));
ELSE
RETURN input;
END IF;
END
WITH `EMPLOYEE` (`empId`, `name`, `email`, `phone`) AS (
SELECT 12345, 'Clark Duff', 'Sales#yahoo.com',9001234567 UNION
SELECT 22245, 'Dave Johnson', 'Accounting#gmail.com',9000123456 UNION
SELECT 55456, 'Ava evelene', 'Sales_Marketing#gmail.com',9000012345
)
SELECT
empId,
someFunc(`name`) AS `name`,
someFunc(`email`) AS `email`,
someFunc(`phone`) AS `phone`
FROM `EMPLOYEE`;
# empId
name
email
phone
12345
Clark Duff
b3282336#yahoo.com
900*****4567
22245
Dave Johnson
47c44ab0#gmail.com
900*****3456
55456
Ava evelene
ab3fee5c#gmail.com
900*****2345
CREATE TRIGGER TR_Update_Member
AFTER UPDATE ON `member`
FOR EACH ROW
BEGIN
DECLARE changeNote VARCHAR(5000) DEFAULT '';
SET changeNote = IF(OLD.Name != NEW.Name,
CONCAT( changeNote,
'Name(',
IFNULL(OLD.Name, '--'),
'->',
IFNULL(NEW.Name, '--'),
'), '
),
changeNote);
SELECT TRIM(TRAILING ', ' FROM changeNote) INTO changeNote;
INSERT INTO `member_change_log`(`Name`) VALUES(changeNote)
END
The above trigger does not insert any data when the name contains null. Could anyone please what is wrong with my code.
The above trigger does not insert any data when the name contains null. Could anyone please what is wrong with my code.
If NEW.Name is NULL then OLD.Name != NEW.Name is NULL too, and IF() executes alternative variant, i.e. you obtain
SET changeNote = changeNote
Simply swap variants:
SET changeNote = IF( OLD.Name = NEW.Name, changeNote, CONCAT( ... ) );
If both OLD.Name and NEW.Name may be NULL then use null-safe compare operator <=> instead of regular compare =.
I want both statements to be executed in my trigger. I can't get the following to work:
IF (flag = 'D') THEN
BEGIN
INSERT INTO logs (id, author_id, action_done, description, old_value, new_value, create_date)
VALUES (null, (SELECT id FROM gallery WHERE flag = 'D'), 'Delete', 'Gallery', (SELECT filename FROM gallery WHERE flag = 'D'), '', NOW());
DELETE FROM gallery WHERE flag = 'D';
END
END IF
I assume id field in logs table is a primary key and auto generated by system.
Try this:
IF (flag = 'D') THEN
BEGIN
INSERT INTO logs (author_id, action_done, description, old_value, new_value, create_date)
select id, 'Delete', 'Gallery', filename, '', NOW() from gallery where flag='D';
DELETE FROM gallery WHERE flag = 'D';
END
END IF
Your id should auto increment and thus should not be one of the values.
Presumably, your trigger is on the table gallery. If so, your trigger should be a "before" or "after" trigger and you can do:
IF (flag = 'D') THEN
BEGIN
INSERT INTO logs (author_id, action_done, description, old_value, new_value, create_date)
VALUES (old.id, 'Delete', 'Gallery', old.filename, '', NOW());
END;
END IF
There is no need to repeat the DELETE.
I came from MSSQL and I'm trying to learn MySQL.
Documentation seem to not help me.
I don't want my query to start always with SELECT, I want my query to SELECT, INSERT or UPDATE depending on the condition. I can't seem to do it with MySQL. Here is my code:
IF COALESCE((SELECT 1 FROM gt_postmeta WHERE meta_value = '12345' LIMIT 1), 0) THEN
BEGIN
INSERT INTO gt_posts (
post_date,
post_content,
post_title,
post_name,
post_type )
VALUES (
'',
'0000493729150.jpg',
'SHAMROCK',
'',
'');
SET #parent_id = (SELECT id FROM gt_posts ORDER BY id DESC LIMIT 1);
INSERT INTO gt_postmeta(
post_id,
meta_key,
meta_value)
VALUES
(#parent_id, '_visibility', 'visible'),
(#parent_id, '_price', 'H72 SEMI-GLOSS DARK EARTH'),
(#parent_id, '_regular_price', 'H72 SEMI-GLOSS DARK EARTH'),
(#parent_id, '_sku', '12345');
INSERT INTO gt_warehouse(
warehouse_id,
stock,
product_sku)
VALUES(
'178',
'',
'12345');
END;
ELSE
BEGIN
IF COALESCE((SELECT 1 FROM gt_warehouse WHERE product_sku = '12345' AND warehouse_id = '178' LIMIT 1), 0) THEN
BEGIN
UPDATE
gt_warehouse SET stock = ''
WHERE product_sku = '12345'
AND warehouse_id = '178';
END;
ELSE
BEGIN
INSERT INTO gt_warehouse(
warehouse_id,
stock,
product_sku)
VALUES (
'',
'',
'',
'12345');
END;
END IF;
END;
END IF;
Follow: You must do the following things to perform this task in MYSQL
1- you have use STORED PROCEDURE in MYSQL to set query block as package exactly as in SQL SERVER but syntax is bit different
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_report`(
------
------
)
BEGIN
--Query block with condition
END;
2- You don't need COALESCE to check the existence of value, you can simply use EXISTS (LIMIT is also optional)
IF EXISTS(SELECT 1 FROM gt_postmeta WHERE meta_value = '12345') THEN
3- After this you may get minor issues like proper use of semicolon, BEGIN & END which you can resolve by yourself.
I think this should work:
SELECT id, login, ( IF(requires='privacy-weight',0,privacy-weight) ) AS privacy-weight, requires
FROM [mytable]
WHERE [mywhereclause]
For more information on how the IF function works in MySQL see the docs at http://dev.mysql.com/doc/refman/5.5/en/if.html
How do I replace non-existent records with not found in the following query. Right now I'm just getting the records that are found.
SELECT CASE WHEN `Name` IS NOT NULL THEN `Name` ELSE 'Not Found' END AS Name
FROM `studentDetails`
WHERE `Transaction_ID` IN('496018490c1d5d60beb5', '77888f084c8a0e7578f5')
My input is
'496018490c1d5d60beb5',
'77888f084c8a0e7578f5'
What I'm getting is
Vinod Tonde
My desired output is
Not Found
Vinod Tonde
The Database looks like
I think what you want is this:
SELECT Transaction_ID, CASE WHEN count(*)>0 THEN `Name` ELSE 'Not Found' END AS Name
FROM `studentDetails`
WHERE `Transaction_ID` IN('496018490c1d5d60beb5', 'b6836a07a3c49af6187f')
group by Transaction_ID
OR, using this you could also try:
SELECT IFNULL(Name, 'Not Found') AS Name
FROM (SELECT '496018490c1d5d60beb5' as col
union all
SELECT 'b6836a07a3c49af6187f') temp_table
LEFT JOIN studentDetails
ON temp_table.col=studentDetails.Transaction_ID collate utf8mb4_unicode_ci
Try this:
UPDATE `studentDetails` SET `Name` = 'Not Found' WHERE (`Name` IS NULL OR `Name` = '') AND `Transaction_ID` IN('496018490c1d5d60beb5', 'b6836a07a3c49af6187f')
You can add a few more alternatives to your case
SELECT CASE
WHEN Name IS NULL THEN 'Not Found'
WHEN length(trim(Name)) = 0 THEN 'Not Found'
ELSE Name
END AS Name
FROM studentDetails
WHERE Transaction_ID IN('496018490c1d5d60beb5', 'b6836a07a3c49af6187f')
Edit
Since it seems that one of those two transaction_id doesn't exist in the database at all, you probably need something like this instead
select coalesce(t2.Name, 'Not Found') as Name
from (select '77888f084c8a0e7578f5' as trans union all select '496018490c1d5d60beb5') t1
left join
studentDetails t2
on t1.trans = t2.Transaction_ID
Create a table for the ids to search:
CREATE TABLE ids (id VARCHAR(30));
Create a procedure to split a list of ids separated by a ',' and insert them into the ids table:
CREATE PROCEDURE split_id_list(IN input VARCHAR(300))
BEGIN
DECLARE tot_length int;
DECLARE sub_length int;
my_loop: LOOP
SET tot_length = CHAR_LENGTH(input);
INSERT INTO ids (id) VALUES(SUBSTRING_INDEX(input, ',', 1));
SET sub_length = CHAR_LENGTH(SUBSTRING_INDEX(input, ',', 1))+2;
SET input = MID(input, sub_length, tot_length);
IF input = '' THEN
LEAVE my_loop;
END IF;
END LOOP my_loop;
END;
Create a procedure to generate view containing the results:
CREATE PROCEDURE idsNames(IN id_list VARCHAR(500))
BEGIN
DECLARE a INT;
DECLARE cur1 CURSOR for select count(*) FROM ids;
OPEN cur1;
FETCH cur1 into a;
IF a > 0
THEN DELETE FROM ids;
END IF;
CLOSE cur1;
call split_id_list(id_list);
CREATE OR REPLACE VIEW RESULTS(r_id,r_name) AS
(SELECT ids.id, CASE WHEN Name IS NULL then 'NotFound' ELSE Name END
FROM studentDetails
RIGHT JOIN ids
ON studentDetails.Transaction_ID = ids.id);
END;
Once the table and the procedures are created, each time you want to execute them, just execute the procedure with the required ids and a select from the view:
CALL idsNames('496018490c1d5d60beb5,b6836a07a3c49af6187f');
SELECT r_name FROM RESULTS;