有没有办法将一个字符串拆分为多个字符串?

时间:2019-01-17 08:21:54

标签: mysql

我有运行在数据库后面的软件,该软件通过GUID将下拉列表中的所有值保存到一栏中。 由于可以在这一栏中保存多个GUID,因此我需要将字符串拆分为多个字符串。

有人知道该怎么做吗? 字符串如下所示,但是可能具有比这两个值更多的值(在“”之间,以避免被标识为标头。)

#1$,{8312aeeb-3a90-4c56-b58e-e4597d2a18ac},{2a8d152b-1ea4-4a63-ae63-db011deb6dea}

这是针对MySQL 2012服务器的。我一直在互联网上寻找潜在的解决方案,其中大多数人都说要创建自己的拆分功能。可悲的是,当我阅读它们时,我不了解它们的确切功能,因此我很难填写正确的名称/值。

我希望输出为:

  

{8312aeeb-3a90-4c56-b58e-e4597d2a18ac}

     

{2a8d152b-1ea4-4a63-ae63-db011deb6dea}

  

8312aeeb-3a90-4c56-b58e-e4597d2a18ac

     

2a8d152b-1ea4-4a63-ae63-db011deb6dea

我将把结果用作子查询。目的是进行完全动态的查询。

3 个答案:

答案 0 :(得分:0)

您正在寻找类似的东西吗?:

SELECT g.id,
    SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(',',g.myguid,','), ',', sep.id), ',' , -1) AS newguid
FROM guid g
CROSS JOIN ( SELECT 3 AS id UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7  UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 ) AS sep
HAVING newguid != ''
ORDER BY g.id,sep.id;

样本

MariaDB []> select * from guid;
+----+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | myguid                                                                                                                                                  |
+----+---------------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | #1$,{8312aeeb-3a90-4c56-b58e-e4597d2a18ac},{2a8d152b-1ea4-4a63-ae63-db011deb6dea}                                                                       |
|  2 | #1$,{8312aeeb-3a90-4c56-b58e-e4597d2aFFFF}                                                                                                              |
|  3 | #1$,{8312aeeb-AAAA-4c56-b58e-e4597d2a18ac},{BBBB-1ea4-4a63-ae63-db011deb6dea},{8312aeeb-CCCC-4c56-b58e-e4597d2a18ac},{EEEE-1ea4-4a63-ae63-db011deb6dea} |
+----+---------------------------------------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.000 sec)

MariaDB []> SELECT g.id,
    ->     SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(',',g.myguid,','), ',', sep.id), ',' , -1) AS newguid
    -> FROM guid g
    -> CROSS JOIN ( SELECT 3 AS id UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7  UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 ) AS sep
    -> HAVING newguid != ''
    -> ORDER BY g.id,sep.id;
+----+----------------------------------------+
| id | newguid                                |
+----+----------------------------------------+
|  1 | {8312aeeb-3a90-4c56-b58e-e4597d2a18ac} |
|  1 | {2a8d152b-1ea4-4a63-ae63-db011deb6dea} |
|  2 | {8312aeeb-3a90-4c56-b58e-e4597d2aFFFF} |
|  3 | {8312aeeb-AAAA-4c56-b58e-e4597d2a18ac} |
|  3 | {BBBB-1ea4-4a63-ae63-db011deb6dea}     |
|  3 | {8312aeeb-CCCC-4c56-b58e-e4597d2a18ac} |
|  3 | {EEEE-1ea4-4a63-ae63-db011deb6dea}     |
+----+----------------------------------------+
7 rows in set (0.001 sec)

MariaDB []>

答案 1 :(得分:0)

MySQL不像PHP或许多其他语言那样具有字符串拆分/爆炸功能。

它可以在定界符上分割字符串,但不允许您几乎一样轻松地访问数组的每个元素。 您说您正在GUI中填充一个下拉列表。使用最可能具有易于操作的字符串拆分功能的GUI语言会更容易吗?

目前,我无法想到一种将每个元素作为一行返回的方法,而只能想到如何在返回的记录集中的单独列中返回每个值。

您将需要在查询中创建自己的“函数”。让我看看是否可以向您展示示例,然后提供比我在几分钟内发现的大多数匹配中显示的内容更多的解释。警告:由于您的示例中可能包含1,2,3 ... n个“元素”,因此您必须具有真正的创造性来处理重复项。 -如果您将查询设置为从具有三个值的行中检索四个元素,则返回的第三个和第四个值将相同。

我在过去几分钟中发现的大多数示例在自由切换正数和负数方面都做得很好,然后让您尝试了解如何/为什么/何时从正数切换为负数。

对于许多您希望达到最大值的元素,请将其用作模型:

SELECT ...,    
SUBSTRING_INDEX(SUBSTRING_INDEX(guid, '.', n), '.', -1) as xxx,
...
FROM my_table

MySQL像在代数中一样处理函数-首先开始处理内部括号,然后找到出路。

此函数的内部部分(SUBSTRING_INDEX(guid,'。',n))在'。'上拆分字符串。定界符,然后保留前“ n”个部分。该函数的外部部分将拆分其在内存中保留的内容,然后返回最后(-1)部分。

使用此模型,您可以更轻松地了解它的工作原理,并且当您几个月前看到此代码时,可以更好地记住自己现在在做什么。

SELECT ...,
SUBSTRING_INDEX(SUBSTRING_INDEX(guid, '.', 1), '.', -1) as guid_1,
SUBSTRING_INDEX(SUBSTRING_INDEX(guid, '.', 2), '.', -1) as guid_2,
SUBSTRING_INDEX(SUBSTRING_INDEX(guid, '.', 3), '.', -1) as guid_3,
SUBSTRING_INDEX(SUBSTRING_INDEX(guid, '.', 4), '.', -1) as guid_4,
SUBSTRING_INDEX(SUBSTRING_INDEX(guid, '.', 5), '.', -1) as guid_5,
...
FROM my_table

处理查询中的重复项将变得非常混乱。这是为只有四个元素的行的第五个元素返回一个空字符串的方法:

IF(substring_index(SUBSTRING_INDEX(guid, '.', 4), '.', -1) != 
    SUBSTRING_INDEX(SUBSTRING_INDEX(guid, '.', 5), '.', -1), 
    SUBSTRING_INDEX(SUBSTRING_INDEX(guid, '.', 5), '.', -1), 
    '') as guid_5

如果服务器管理员允许,可以通过在MySQL服务器上创建用户功能来简化此操作。我将创建以下函数:

create function MY_SUBSTRING (
  search_string text,
  delimiter_chars varchar(1),
  string_index int
)
RETURNS varchar(128) DETERMINISTIC
BEGIN
    # FIRST ARRAY ELEMENT IS INDEX 1, NOT INDEX 0
    RETURN SUBSTRING_INDEX(SUBSTRING_INDEX(search_string, delimiter_chars, string_index), delimiter_chars, -1);
END $$

这将为您提供一些干净且可重用的代码,从而使此查询和其他查询更简洁,例如

SELECT ...,
MY_SUBSTRING(guid, '.', 1) as guid_1,
MY_SUBSTRING(guid, '.', 2) as guid_2,
MY_SUBSTRING(guid, '.', 3) as guid_3,
MY_SUBSTRING(guid, '.', 4) as guid_4,
MY_SUBSTRING(guid, '.', 5) as guid_5,
...
FROM my_table

糟糕-我刚刚看到您想将结果用作子查询。那是另一种蠕虫,需要有人将结果从列转移到行。至少,我希望这可以帮助您更好地了解SUBSTRING_INDEX函数。

答案 2 :(得分:0)

我向你建议一些计划
计划A:
您可以使用具有多个值的选择

<select id='mySelect'>
    <option value="8312aeeb-3a90-4c56-b58e-e4597d2a18ac" 
            data-val1="val1" 
            data-val2="val2" 
            data-val3="val3"> item1</option>
</select>

您可以在jquery中获得价值

var val1 = $("#mySelect option:selected").data('val1');
var val2 = $("#mySelect option:selected").data('val2');
var val3 = $("#mySelect option:selected").data('val3');

然后将它们发送到服务器

  PLoading.Start();
 $.ajax({
                type: "GET",
                url: '/user/login',
                data: { val1 : val1 },
                dataType: "json",
                success: function (response) {                   

                },
                error: function (response) {
                    PAlert.ErrorAlert("بروز خطا");
                },
                complete: function () {
                    PLoading.Stop();
                }
            });

计划B
您可以使用新表将Guid字段连接到其他字段/表列
新表的shema

| Guid | val1 | val2 | val3 |