Skip to content

Instantly share code, notes, and snippets.

@num8er
Last active February 10, 2024 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save num8er/89d41bda87a0d8ccb6b254d822f9f230 to your computer and use it in GitHub Desktop.
Save num8er/89d41bda87a0d8ccb6b254d822f9f230 to your computer and use it in GitHub Desktop.
MySQL stored function to convert formula to list of numbers
# 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;
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