Last active
February 10, 2024 15:28
-
-
Save num8er/89d41bda87a0d8ccb6b254d822f9f230 to your computer and use it in GitHub Desktop.
MySQL stored function to convert formula to list of numbers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Given alphanumeric string that includes two special characters + and -. | |
# Dash "-" means range, "+" (plus) means inclusion of number to list. | |
# Please execute RangeFormulaToList.sql to create function before running test below. | |
# Examples: | |
DROP TABLE IF EXISTS `tests_formulas`; | |
CREATE TABLE `tests_formulas` ( | |
`id` int(11) unsigned NOT NULL AUTO_INCREMENT, | |
`formula` text DEFAULT NULL, | |
PRIMARY KEY (`id`) | |
) ENGINE=InnoDB; | |
INSERT INTO `tests_formulas` (`id`, `formula`) | |
VALUES | |
(1, '1-3+5'), | |
(2, '10-20+30'), | |
(3, '1-9+10+11-19'); | |
SELECT | |
formula, | |
RangeFormulaToList(formula) as list | |
FROM tests_formulas; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DELIMITER // | |
CREATE FUNCTION RangeFormulaToList(input_string VARCHAR(255)) | |
RETURNS TEXT | |
DETERMINISTIC | |
BEGIN | |
DECLARE output_list TEXT DEFAULT ''; | |
DECLARE current_part VARCHAR(255); | |
DECLARE range_start INT; | |
DECLARE range_end INT; | |
DECLARE range_separator_pos INT; | |
DECLARE plus_separator_pos INT; | |
DECLARE current_number INT; | |
DECLARE delimiter_pos INT; | |
-- Replace '+' with ',' | |
SET input_string = REPLACE(input_string, '+', ','); | |
-- Add a comma at the end to ensure the last number is processed | |
SET input_string = CONCAT(input_string, ','); | |
-- Process each part of the input string | |
WHILE LENGTH(input_string) > 0 DO | |
-- Find the position of the next comma delimiter | |
SET delimiter_pos = INSTR(input_string, ','); | |
-- Extract the current part | |
SET current_part = TRIM(SUBSTRING(input_string, 1, delimiter_pos - 1)); | |
-- Remove the processed part from the input string | |
SET input_string = SUBSTRING(input_string, delimiter_pos + 1); | |
-- Find the position of the range separator '-' | |
SET range_separator_pos = INSTR(current_part, '-'); | |
IF range_separator_pos > 0 THEN | |
-- If a range separator is found | |
SET range_start = CAST(SUBSTRING_INDEX(current_part, '-', 1) AS UNSIGNED); | |
SET range_end = CAST(SUBSTRING_INDEX(current_part, '-', -1) AS UNSIGNED); | |
-- Append the range to the output list | |
WHILE range_start <= range_end DO | |
SET output_list = CONCAT(output_list, IF(output_list = '', '', ','), range_start); | |
SET range_start = range_start + 1; | |
END WHILE; | |
ELSE | |
-- If no range separator is found, it's a single number | |
SET current_number = CAST(current_part AS UNSIGNED); | |
SET output_list = CONCAT(output_list, IF(output_list = '', '', ','), current_number); | |
END IF; | |
END WHILE; | |
RETURN (output_list); | |
END// | |
DELIMITER ; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment