简体   繁体   中英

How to write a SQL query that selects a substring of variable length

I'm currently working with data which consists of strings in the following format:

"{Weight: 250g}{Color: Red}{Variety: Honeycrisp}{Expiration: Jun 15}"

This data is currently in one column, but I'm trying to parse the data so that the end result is 4 separated columns (Weight, Color, Variety, and Expiration). I tried using the SUBSTRING() function, but am running into issues as the length of each part varies from row to row of the data. Would you suggest using a different function?

The following is for MySQL . Based on https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_substring-index

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('{Weight: 250g}{Color: Red}{Variety: Honeycrisp}{Expiration: Jun 15}', '}{Color: ', 1), 'Weight: ', -1) as Weight;

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('{Weight: 250g}{Color: Red}{Variety: Honeycrisp}{Expiration: Jun 15}', '}{Variety: ', 1), 'Color: ', -1) as Color;

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('{Weight: 250g}{Color: Red}{Variety: Honeycrisp}{Expiration: Jun 15}', '}{Expiration: ', 1), 'Variety: ', -1) as Variety;

SELECT TRIM(TRAILING '}' from SUBSTRING_INDEX('{Weight: 250g}{Color: Red}{Variety: Honeycrisp}{Expiration: Jun 15}', 'Expiration: ', -1))as Expiration;

Based on this a function would be easier to write to insert to other table or extract these values.

DELIMITER $$
DROP FUNCTION IF EXISTS ExtractKeyValues $$
CREATE FUNCTION ExtractKeyValues(input text, Key_ varchar(50)) RETURNS VARCHAR(10)
    DETERMINISTIC
BEGIN
    DECLARE res varchar(50);

    Case 
        when key_ = 'Weight' THEN
            SET res = SUBSTRING_INDEX(SUBSTRING_INDEX(input, '}{Color: ', 1), 'Weight: ', -1);
        when Key_ = 'Color' THEN
            SET res = SUBSTRING_INDEX(SUBSTRING_INDEX(input, '}{Variety: ', 1), 'Color: ', -1);
        when key_ = 'Variety' THEN
            SET res = SUBSTRING_INDEX(SUBSTRING_INDEX(input, '}{Expiration: ', 1), 'Variety: ', -1);
        when key_ = 'Expiration' THEN
            SET res = TRIM(TRAILING '}' from SUBSTRING_INDEX(input, 'Expiration: ', -1));
    END CASE;

    RETURN (res);
END; $$
Delimiter ;

To use this we can do:

select ExtractKeyValues('{Weight: 250g}{Color: Red}{Variety: Honeycrisp}{Expiration: Jun 15}', 'Weight');
select ExtractKeyValues('{Weight: 250g}{Color: RED}{Variety: Honeycrisp}{Expiration: Jun 15}', 'Color');
select ExtractKeyValues('{Weight: 250g}{Color: Red}{Variety: Honeycrisp}{Expiration: Jun 15}', 'Variety');
select ExtractKeyValues('{Weight: 250g}{Color: Red}{Variety: Honeycrisp}{Expiration: Jun 15}', 'Expiration');

Just replace the variable @Data with your Data

DECLARE @Data varchar(1000)
SET @Data = '{Weight: 250g}{Color: Red}{Variety: Honeycrisp}{Expiration: Jun 15}'

DECLARE @EndPos int
SET @EndPos = CHARINDEX('}', @Data, 0)
SELECT SUBSTRING(@Data,  9, @EndPos - 9) AS Weight

SET @Data = SUBSTRING(@Data, @EndPos + 1, LEN(@Data))
SET @EndPos = CHARINDEX('}', @Data, 0)
SELECT SUBSTRING(@Data,  8, @EndPos - 8) AS Color


SET @Data = SUBSTRING(@Data, @EndPos + 1, LEN(@Data))
SET @EndPos = CHARINDEX('}', @Data, 0)
SELECT SUBSTRING(@Data,  10, @EndPos - 10) AS Variety

SET @Data = SUBSTRING(@Data, @EndPos + 1, LEN(@Data))
SET @EndPos = CHARINDEX('}', @Data, 0)
SELECT SUBSTRING(@Data,  13, @EndPos - 13) AS Expiration

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM