栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

我可以使用纯MySQL解决此问题吗?(在列中以';'分隔的值连接)

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

我可以使用纯MySQL解决此问题吗?(在列中以';'分隔的值连接)

如果

user_resources
(t1)是一个“归一化表”,每个
user =>resource
组合有一行,那么获取答案的查询将与将
joining
表放在一起一样简单。

las,是

denormalized
通过将
resources
列作为:“资源ID列表”,并用“;”分隔 字符。

如果我们可以将’resources’列转换为行,那么随着表联接变得简单,很多困难就会消失。

查询生成的输出要求:

SELECt user_resource.user,        resource.dataFROM user_resource      JOIN integerseries AS isequence        ON isequence.id <= COUNT_IN_SET(user_resource.resources, ';')      JOIN resource        ON resource.id = VALUE_IN_SET(user_resource.resources, ';', isequence.id)      ORDER BY       user_resource.user,  resource.data

输出:

user        data    ----------  --------sampleuser  abcde   sampleuser  azerty  sampleuser  qwerty  stacky      qwerty  testuser    abcde   testuser    azerty

怎么样:

“技巧”是要有一个表格,其中包含从1到某个限制的数字。我叫它

integerseries
。它可以用于将“水平”事物转换
';' delimitedstrings
rows

这种工作方式是,当您与进行“联接” 时

integerseries
,您正在执行
cross join
,这就是“内部联接”“自然”发生的事情。

每行都

integerseries
使用与表不同的“序列号”重复,我们将其用作列表中“资源”的“索引”,以用于此目的
row

这个想法是:

  • 计算列表中的项目数。
  • 根据项目在列表中的位置提取每个项目。
  • 使用
    integerseries
    一个行转换成一组行提取个人“资源ID”的
    user
    resources
    随着我们的前进。

我决定使用两个功能:

  • 给定“分隔字符串列表”和“索引”的函数将返回列表中该位置的值。我称之为:

    VALUE_IN_SET
    。即给定“ A; B; C”和“索引”为2,则返回“ B”。

  • 给定“分隔字符串列表”的函数将返回列表中项目数的计数。我称之为:

    COUNT_IN_SET
    。即给定“ A; B; C”将返回3

事实证明,这两个功能

integerseries
应该为
delimited items list in a column

它行得通吗?

从中创建“规范化”表的查询

';' delimited string incolumn
。它显示所有列,包括由于’cross_join’(
isequence.id
as
resources_index
)而产生的值:

SELECt user_resource.user,        user_resource.resources,       COUNT_IN_SET(user_resource.resources, ';')     AS resources_count,        isequence.id  AS resources_index,       VALUE_IN_SET(user_resource.resources, ';', isequence.id)  AS resources_valueFROM      user_resource      JOIN  integerseries AS isequence        ON  isequence.id <= COUNT_IN_SET(user_resource.resources, ';')ORDER BY       user_resource.user, isequence.id

“规范化”表输出:

user        resources  resources_count  resources_index  resources_value  ----------  ---------  ---------------  ---------------  -----------------sampleuser  1;2;3         3     1  1     sampleuser  1;2;3         3     2  2     sampleuser  1;2;3         3     3  3     stacky      2  1     1  2     testuser    1;32     1  1     testuser    1;32     2  3

使用上面的“规范化”

user_resources
表,它是提供所需输出的简单联接:

所需的功能这些通用功能可在任何地方使用

注意:这些函数的名称与mysql
FIND_IN_SET函数有关。即他们在字符串列表方面做类似的事情?

COUNT_IN_SET
函数:返回的数
character delimited items
列。

DELIMITER $$DROP FUNCTION IF EXISTS `COUNT_IN_SET`$$CREATE FUNCTION `COUNT_IN_SET`(haystack VARCHAr(1024),          delim CHAr(1)         ) RETURNS INTEGERBEGIN      RETURN CHAR_LENGTH(haystack) - CHAR_LENGTH( REPLACE(haystack, delim, '')) + 1;END$$DELIMITER ;

VALUE_IN_SET
功能:在对待
delimited list
作为
one based array
并返回在给定的“索引”的值。

DELIMITER $$DROP FUNCTION IF EXISTS `VALUE_IN_SET`$$CREATE FUNCTION `VALUE_IN_SET`(haystack VARCHAr(1024),          delim CHAr(1),          which INTEGER         ) RETURNS VARCHAr(255) CHARSET utf8 COLLATE utf8_unipre_ciBEGIN      RETURN  SUBSTRING_INDEX(SUBSTRING_INDEX(haystack, delim, which),          delim,          -1);END$$DELIMITER ;

相关信息:

  • 最终弄清楚了如何获得SQLFiddle-工作代码来编译函数。

  • 有一个适用于

    SQLite
    数据库的版本,也适用于SQLite-规范级联的字段并与之联接?

表格(含数据):

CREATE TABLE `integerseries` (  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=utf8 COLLATE=utf8_unipre_ci;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);

资源:

CREATE TABLE `resource` (  `id` int(11) NOT NULL,  `data` varchar(250) COLLATE utf8_unipre_ci DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unipre_ci;insert  into `resource`(`id`,`data`) values (1,'abcde');insert  into `resource`(`id`,`data`) values (2,'qwerty');insert  into `resource`(`id`,`data`) values (3,'azerty');

用户资源:

CREATE TABLE `user_resource` (  `user` varchar(50) COLLATE utf8_unipre_ci NOT NULL,  `resources` varchar(250) COLLATE utf8_unipre_ci DEFAULT NULL,  PRIMARY KEY (`user`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unipre_ci;insert  into `user_resource`(`user`,`resources`) values ('sampleuser','1;2;3');insert  into `user_resource`(`user`,`resources`) values ('stacky','3');insert  into `user_resource`(`user`,`resources`) values ('testuser','1;3');


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/416449.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号