MySql使用Java中的查询查找单词之间的匹配项

时间:2018-11-26 02:50:17

标签: java mysql jdbc

我有连接到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 ++将使此错误重复运算符操作数无效。 My Table

表的列数据:

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

我试图在第一个查询中在%之前放置一个空格,以进行区分。我的问题现在是如何在一个列中搜索多个单词,以上查询对两个或三个输入按准确顺序起作用。搜索javascript和html会显示,但是javascript和css不会显示,因为它的顺序不正确

3 个答案:

答案 0 :(得分:0)

让我猜,您将所有开发人员存储在一个表中,其中一列存储该开发人员掌握的语言。

当有人输入一种语言时,您要搜索所有掌握该语言的开发人员吗?

如果是这样,我会在您的语言列中的语言列中,在末尾添加一个额外的空格(使用_作为下面的空格)

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() + "_%")

答案 1 :(得分:0)

您的问题是您的数据库模型不正确normalized。如果可能,建议不要在数据库的一列中存储多个值。相反,作为第一步,请使用单独的数据库来存储编程语言,并使用唯一索引将值映射到人员:

people

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

languages

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

现在,您可以在表格LANGUAGES中搜索相应的语言,并使用JOIN子句将其映射给用户:

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

但是,仍然有优化的空间:语言表中现在每种编程语言都有多个条目。例如,如果您不小心在同一语言的一项输入中有错字,则这将花费更长的时间进行搜索,并且有可能导致数据库不一致。 为了避免所有这些情况,我们可以引入第三个表,每个表仅包含一个条目,并将第二个表重构为仅一个映射:

 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++

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

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#'

现在每种语言只有一个条目,您可以轻松搜索每种语言并获得所有映射的用户,并且可以添加单个新的语言或映射,而无需完全修改users表。

这是数据模型的规范化形式。

答案 2 :(得分:0)

这是执行查询的一种方法。这是从此post派生的。

这需要一个 temporary 表,该表的行数由数字填充,最多可达到令牌的最大数量(用空格分隔的语言字符串,例如,字符串“ 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     |
+------+-------+