0

In MySQL, how would I select each character in a given string as individual rows, if the length of the string is unknown. For example, if I have the string:

SET @str:='abc';

I would like a SELECT statement to produce:

rownum  char
======  ====
1       a
2       b
3       c

If possible, I would like to avoid temp tables or stored procedures.

user1822391
  • 399
  • 3
  • 13
  • Look at this answer https://stackoverflow.com/questions/14959166/mysql-select-query-get-only-first-10-characters-of-a-value @user1822391 Or Follow this link https://www.w3resource.com/mysql/string-functions/mysql-substring-function.php – Raj Kumar Mar 06 '20 at 17:13
  • use a prepared procedure and use sub_string with a counter – nbk Mar 06 '20 at 17:13
  • It could be done somewhat easily if there's an upper bound to the string length. – Nae Mar 06 '20 at 17:14
  • @Nae, Let assume the upper bound will be 10... what would you suggest to accomplish this? – user1822391 Mar 06 '20 at 17:24
  • @Raj Kumar This question is not related to my question... I am looking to have each char of a string selected as individual rows, not select the first X chars from a string. – user1822391 Mar 06 '20 at 17:27
  • @user1822391, What is your MySQL version. – Ankit Bajpai Mar 06 '20 at 17:41

2 Answers2

2
SELECT @var_i + 1 AS rownum, SUBSTR(@var_str, (@var_i := @var_i + 1), 1) AS `char`
FROM (SELECT (@var_str := "abc") AS _, (@var_i := 0) AS __) AS pow0
CROSS JOIN (SELECT 0 AS _ UNION ALL SELECT 0) AS pow1
CROSS JOIN (SELECT 0 AS _ UNION ALL SELECT 0) AS pow2
CROSS JOIN (SELECT 0 AS _ UNION ALL SELECT 0) AS pow3
CROSS JOIN (SELECT 0 AS _ UNION ALL SELECT 0) AS pow4 -- 8 < 10 < 16
WHERE @var_i < CHAR_LENGTH(@var_str)
;
Nae
  • 14,209
  • 7
  • 52
  • 79
  • 1
    I like your idea... if I know the upper bound & do not want to use stored procedure & temp tables. I modified your SQL statement to limit to not show the empty rows with ```WHERE @var_i < CHAR_LENGTH(@var_str)```. – user1822391 Mar 06 '20 at 18:30
1

With this procedure

CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_splitstring`(IN _s TEXT)
BEGIN
DECLARE _i INTEGER;
DECLARE _n INTEGER;
DROP TABLE IF EXISTS listchar;
CREATE TEMPORARY TABLE listchar ( singlechar varchar(1));
SELECT LENGTH(_s) INTO _i;
SET _n = 0;
    loop_label:  LOOP
        IF  _n > _i THEN 
            LEAVE  loop_label;
        END  IF;

        SET  _n = _n + 1;
        INSERT INTO listchar SELECT SUBSTRING(_s,_n,1);
    END LOOP;
SELECT * FROM listchar;
DROP TABLE listchar;
END

Result:

Result

nbk
  • 45,398
  • 8
  • 30
  • 47