mysql在java中使用查询查找单词之间的匹配

wpx232ag  于 2021-06-17  发布在  Mysql
关注(0)|答案(3)|浏览(361)

我有一个连接到mysql数据库的java程序。我要做的是获取用户输入并显示与用户输入匹配的列。该列包含编程语言列表。我需要sql查询方面的帮助。例如,如果第一行中的列包含javascript、c++、c#,第二行中的列包含java,并且如果我使用了查询

"SELECT * from Language WHERE Programming Languages LIKE'%"+input.getText()+"%'")

如果用户搜索java,那么表将显示包含java和javascript的列,因为它包含单词java。如果有第三行,并且该列有c,如果用户要搜索c,那么它将显示包含c++和c的列。
我试着用这个正则表达式来代替

`"SELECT * from Language WHERE Programming Language REGEXP'[[<:]]"+input.getText()+"[[:>:]]'")`

它解决了java和javascript问题,但是搜索c将显示带有c#和c的列。同时,搜索c#将不显示任何内容,搜索c将使此错误重复运算符操作数无效。我的table
表的列数据:

Javascript HTML CSS PHP
C# Java
C
C++ C#

在第一个查询中,我试图在%前面加一个空格,这个空格用于区分。我现在的问题是如何在一列中搜索多个单词,上面的查询按确切的顺序处理两个或三个输入。搜索javascript和html会显示出来,但是javascript和css不会显示,因为它不符合顺序

nx7onnlm

nx7onnlm1#

下面是一种执行查询的方法。这是从这篇文章衍生出来的。
这需要一个临时表,其中的行数由数字填充,最多可包含最大的标记数(用空格分隔的语言字符串,例如字符串“javascript html css php”有4个标记)。
创建带有数字的临时表:

create temporary table temp_numbers as
    select 1 as num
    union all select 2 as num
    union all select 3 as num
    union all select 4 as num
    union all select 5 as num
;

包含编程语言字符串列的表:

create table test_langs (
    col1 varchar(10) NOT NULL,
    col2 varchar(50) NOT NULL
);

插入一些测试数据:

insert into test_langs values ('ID-1', 'Javascript HTML CSS PHP');
insert into test_langs values ('ID-2', 'C# Java');
insert into test_langs values ('ID-3', 'C');
insert into test_langs values ('ID-4', 'C# C++');
insert into test_langs values ('ID-5', 'Python Java LUA');

查询:
此选择与输入字符串“c”完全匹配;

select col1, token from (
    select col1, substring_index(
        substring_index(col2, ' ', num), 
        ' ', 
        -1
    ) as token
from test_langs
join temp_numbers
    on char_length(col2) - char_length(replace(col2, ' ', '')) >= num - 1
) as individual_progamming_languages
where token='C';

结果是:

+------+-------+
| col1 | token |
+------+-------+
| ID-3 | C     |
+------+-------+
vhipe2zx

vhipe2zx2#

这里的问题是数据库模型没有正确规范化。虽然可能,但不建议在数据库的一列中存储多个值。相反,作为第一步,使用单独的数据库存储编程语言,并使用唯一索引将值Map到人员:

people

id    | name | other stuff
86511 | Bob  | ...         
86513 | TBA  | ...

.

languages

language | user_id
C#       | 86511
Java     | 86511
C++      | 86513
C#       | 86513

现在您只需在表语言中搜索相应的语言,并使用join子句将其Map到用户:

SELECT *
FROM languages
  INNER JOIN people ON languages.user_id = people.id
WHERE languages.language = 'C#';

但是,仍然有优化的空间:现在在languages表中,每种编程语言都有多个条目。例如,如果您不小心在同一语言的一个条目中输入了一个错别字,那么这需要更长的搜索时间,并且有可能导致数据库不一致。为了避免所有这些,我们可以引入第三个表,每个语言只包含一个条目,然后将第二个表重新构造为一个Map:

people

id    | name | other stuff
86511 | Bob  | ...         
86513 | TBA  | ...

.

lang_mapping

lang_id | user_id
1       | 86511
2       | 86511
3       | 86513
1       | 86513

.

languages

id | language
1  | C#
2  | Java
3  | C++

通过向查询引入另一个联接,您仍然可以查询表并将语言连接到usery:

SELECT *
FROM languages
  INNER JOIN lang_mapping ON lang_mapping.lang_id = language.id
  INNER JOIN people ON lang_mapping.user_id = people.id
WHERE languages.language = 'C#'

现在,每种语言只有一个条目,您可以轻松地搜索每种语言并获取所有Map用户,还可以添加单独的新语言或Map,而无需修改users表。
这是数据模型的规范化形式。

zaqlnxep

zaqlnxep3#

让我猜猜,您将所有开发人员存储到一个表中,其中一列存储此开发人员掌握的语言。
当有人输入一种语言时,你想搜索所有掌握这种语言的开发人员吗?
如果是这样的话,我会这样做,在你的语言栏,在你的语言栏,在末尾加一个额外的空格(使用 _ 如下空白)

Javascript_HTML_CSS_PHP_
C#_Java_
C++_C#_
C_
Python_Java_LUA_

然后在java代码中,可以使用以下代码来实现这一点。

SELECT * from Language WHERE Programming_Languages LIKE'%"+input.getText()+"_%'")

请注意不要在java代码中连接sql字符串。你可以这样做:

statment = con.prepare("SELECT * from Language WHERE Programming_Languages LIKE ?")
statment.setString(1, "%" + input.getText() + "_%")

相关问题