MySQL String separation by comma operator

后端 未结 2 1648
青春惊慌失措
青春惊慌失措 2021-02-10 04:56

I have String asdasdwdfef,rgrgtggt,weef and i want output like in table format as shown below

id      decription
1       asdasdwdfef
2       rgrgtgg         


        
相关标签:
2条回答
  • 2021-02-10 05:32

    Requirements: split a 'delimited' column into rows (a table).

    Why? You can use all the SQL Aggregate functions to process the rows.

    Working SQLFiddle

    Related questions that use this code:

    • Count number of unique characters in a string

    • Can I resolve this with pure mysql? (joining on ';' separated values in a column)

    I chose to use:

    • table of integers (integersequence) which when 'inner joined' or 'cross joined' (same thing) to another table will generate rows which are certain to have a unique sequence number starting from 1. This is just using what RDBMS engines are required to do.

    • why a table of integers?: It is small and will get loaded into the cache. It is easy to understand.

    • Rather than have lots of code in the query that obscures what it actually does. I use functions that do one job. It simplifies the main query and can be tested and checked separately. I am only concerned about ease of maintenance and understanding at this point.

    The example here is for one string. However, It can be easily expanded to a table of delimited strings of various sizes. The 'cross join' will create all the possible options of index starting from 1 when joining to integersequence (i really need to use another name :-/).

    So, the query:

    SET @StrToParse = "asdasdwdfef,rgrgtggt,weef";
    
    /* example */
    select integerseries.id,
           count_in_set(@StrToParse, ','),
           value_in_set(@StrToParse, ',', integerseries.id)
    from integerseries
    where integerseries.id <= count_in_set(@StrToParse, ',');
    

    The output:

    PositionOfString, CountOfCommaDelimitedStrings, StringAtThatPosition 
    
    1                 3                             asdasdwdfef
    2                 3                             rgrgtggt
    3                 3                             weef
    

    Now, how do we get those values:

    I chose to use two functions:

    The names are related to the mysql function 'FIND_IN_SET'.

    1) The COUNT_IN_SET function: returns the count of character delimited items in the column.

    CREATE FUNCTION `COUNT_IN_SET`(haystack VARCHAR(1024), 
                                   delim CHAR(1)
                                   ) RETURNS INTEGER
    BEGIN
          RETURN CHAR_LENGTH(haystack) - CHAR_LENGTH( REPLACE(haystack, delim, '')) + 1;
    END$$
    

    2) The VALUE_IN_SET function: treats the delimited list as a one based array and returns the value at the given 'index'.

    CREATE FUNCTION `VALUE_IN_SET`(haystack VARCHAR(1024), 
                                   delim CHAR(1), 
                                   which INTEGER
                                   ) RETURNS VARCHAR(255) CHARSET utf8 COLLATE utf8_unicode_ci
    BEGIN
          RETURN  SUBSTRING_INDEX(SUBSTRING_INDEX(haystack, delim, which),
                         delim,
                         -1);
    END$$
    

    The intereseries table - see (Tally tables)

    CREATE TABLE `integerseries` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    
    /*Data for the table `integerseries` */
    
    insert  into `integerseries`(`id`) values (1);
    insert  into `integerseries`(`id`) values (2);
    insert  into `integerseries`(`id`) values (3);
    insert  into `integerseries`(`id`) values (4);
    insert  into `integerseries`(`id`) values (5);
    insert  into `integerseries`(`id`) values (6);
    insert  into `integerseries`(`id`) values (7);
    insert  into `integerseries`(`id`) values (8);
    insert  into `integerseries`(`id`) values (9);
    insert  into `integerseries`(`id`) values (10);
    
    0 讨论(0)
  • 2021-02-10 05:35

    I got the answer

    First create new function

    CREATE FUNCTION SPLIT_STR(x VARCHAR(255), delim VARCHAR(12), pos INT)
    RETURNS VARCHAR(255)
    RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
    LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1), delim, '');
    

    Then create stored procedure

    DELIMITER ;;
    CREATE PROCEDURE Split(in fullstr varchar(255))
    BEGIN
        DECLARE a INT Default 0 ;
        DECLARE str VARCHAR(255);
    
        DROP TABLE IF EXISTS my_temp_table;
        CREATE temporary TABLE my_temp_table(ID INT AUTO_INCREMENT NOT NULL, description text, primary key(ID));
    
        simple_loop: LOOP
            SET a=a+1;
            SET str=SPLIT_STR(fullstr,",",a);
            IF str='' THEN
                LEAVE simple_loop;
            END IF;
            #Do Inserts into temp table here with str going into the row
            insert into my_temp_table (description) values (str);
       END LOOP simple_loop;
       select * from my_temp_table;
    END
    

    After that when i call it by call Split('asas,d,sddf,dfd'); it gives me the output that what i want.

    Thanx for every suggestion.

    0 讨论(0)
提交回复
热议问题