在子查询mysql上使用REGEXP vs IN
我想使用“相似”表中的数据来查找“发布”表中的结果 表“相似”具有这种结构在子查询mysql上使用REGEXP vs IN,mysql,regex,Mysql,Regex,我想使用“相似”表中的数据来查找“发布”表中的结果 表“相似”具有这种结构 artist similar_artist Moodymann Theo Parrish Moodymann Jeff Mills Moodymann Marcellus Pittman Moodymann Rick Wilhite 到目前为止,我的问题是 SELECT * FROM releases WHERE releases.all_artists REGEXP 'Moodymann' OR
artist similar_artist
Moodymann Theo Parrish
Moodymann Jeff Mills
Moodymann Marcellus Pittman
Moodymann Rick Wilhite
到目前为止,我的问题是
SELECT * FROM releases
WHERE
releases.all_artists REGEXP 'Moodymann'
OR releases.label_no_country='KDJ'
OR releases.all_artists IN (SELECT similar_artist
FROM similar
WHERE artist='Moodymann')
ORDER BY date DESC
“所有艺术家”专栏有如下记录:
Moodymann | Theo Parrish | Rick Wade
Jeff Mills | Moodymann | Rick Wilhite
所以我想要的最终查询基本上是
SELECT * FROM releases
WHERE
releases.all_artists REGEXP 'Moodymann'
OR releases.label_no_country='KDJ'
OR releases.all_artists IN ('Theo Parrish','Jeff Mills','Marcellus Pittman','Rick Wilhite')
要进行匹配,我想我需要使用REGEXP而不是IN-REGEXP返回“Subquery返回超过1行”。如何使用从子查询返回的数据
此外,查询需要很长时间才能运行(最多20秒)-是否有任何方法可以加快运行速度,因为这在我的web应用程序中不可用
谢谢 试试这个SQL
SELECT *
FROM releases
WHERE releases.all_artists LIKE '%Moodymann%'
OR releases.label_no_country='KDJ'
ORDER BY date DESC
MySQL 5.5.30架构设置:
CREATE TABLE Table1
(`artist` varchar(9), `similar_artist` varchar(17))
;
INSERT INTO Table1
(`artist`, `similar_artist`)
VALUES
('Moodymann', 'Theo Parrish'),
('Moodymann', 'Jeff Mills'),
('Moodymann', 'Marcellus Pittman'),
('Moodymann', 'Rick Wilhite')
;
create table allt(allf varchar(50));
insert into allt values('Moodymann | Theo Parrish | Rick Wade'),
('Jeff Mills | Moodymann | Rick Wilhite'),
('Jeff Mills | asdasdadasd | Rick Wilhite');
SELECT *
FROM allt
WHERE allt.allf LIKE '%Moodymann%'
| ALLF |
-----------------------------------------
| Moodymann | Theo Parrish | Rick Wade |
| Jeff Mills | Moodymann | Rick Wilhite |
查询1:
CREATE TABLE Table1
(`artist` varchar(9), `similar_artist` varchar(17))
;
INSERT INTO Table1
(`artist`, `similar_artist`)
VALUES
('Moodymann', 'Theo Parrish'),
('Moodymann', 'Jeff Mills'),
('Moodymann', 'Marcellus Pittman'),
('Moodymann', 'Rick Wilhite')
;
create table allt(allf varchar(50));
insert into allt values('Moodymann | Theo Parrish | Rick Wade'),
('Jeff Mills | Moodymann | Rick Wilhite'),
('Jeff Mills | asdasdadasd | Rick Wilhite');
SELECT *
FROM allt
WHERE allt.allf LIKE '%Moodymann%'
| ALLF |
-----------------------------------------
| Moodymann | Theo Parrish | Rick Wade |
| Jeff Mills | Moodymann | Rick Wilhite |
:
CREATE TABLE Table1
(`artist` varchar(9), `similar_artist` varchar(17))
;
INSERT INTO Table1
(`artist`, `similar_artist`)
VALUES
('Moodymann', 'Theo Parrish'),
('Moodymann', 'Jeff Mills'),
('Moodymann', 'Marcellus Pittman'),
('Moodymann', 'Rick Wilhite')
;
create table allt(allf varchar(50));
insert into allt values('Moodymann | Theo Parrish | Rick Wade'),
('Jeff Mills | Moodymann | Rick Wilhite'),
('Jeff Mills | asdasdadasd | Rick Wilhite');
SELECT *
FROM allt
WHERE allt.allf LIKE '%Moodymann%'
| ALLF |
-----------------------------------------
| Moodymann | Theo Parrish | Rick Wade |
| Jeff Mills | Moodymann | Rick Wilhite |
试试这个SQL
SELECT *
FROM releases
WHERE releases.all_artists LIKE '%Moodymann%'
OR releases.label_no_country='KDJ'
ORDER BY date DESC
MySQL 5.5.30架构设置:
CREATE TABLE Table1
(`artist` varchar(9), `similar_artist` varchar(17))
;
INSERT INTO Table1
(`artist`, `similar_artist`)
VALUES
('Moodymann', 'Theo Parrish'),
('Moodymann', 'Jeff Mills'),
('Moodymann', 'Marcellus Pittman'),
('Moodymann', 'Rick Wilhite')
;
create table allt(allf varchar(50));
insert into allt values('Moodymann | Theo Parrish | Rick Wade'),
('Jeff Mills | Moodymann | Rick Wilhite'),
('Jeff Mills | asdasdadasd | Rick Wilhite');
SELECT *
FROM allt
WHERE allt.allf LIKE '%Moodymann%'
| ALLF |
-----------------------------------------
| Moodymann | Theo Parrish | Rick Wade |
| Jeff Mills | Moodymann | Rick Wilhite |
查询1:
CREATE TABLE Table1
(`artist` varchar(9), `similar_artist` varchar(17))
;
INSERT INTO Table1
(`artist`, `similar_artist`)
VALUES
('Moodymann', 'Theo Parrish'),
('Moodymann', 'Jeff Mills'),
('Moodymann', 'Marcellus Pittman'),
('Moodymann', 'Rick Wilhite')
;
create table allt(allf varchar(50));
insert into allt values('Moodymann | Theo Parrish | Rick Wade'),
('Jeff Mills | Moodymann | Rick Wilhite'),
('Jeff Mills | asdasdadasd | Rick Wilhite');
SELECT *
FROM allt
WHERE allt.allf LIKE '%Moodymann%'
| ALLF |
-----------------------------------------
| Moodymann | Theo Parrish | Rick Wade |
| Jeff Mills | Moodymann | Rick Wilhite |
:
CREATE TABLE Table1
(`artist` varchar(9), `similar_artist` varchar(17))
;
INSERT INTO Table1
(`artist`, `similar_artist`)
VALUES
('Moodymann', 'Theo Parrish'),
('Moodymann', 'Jeff Mills'),
('Moodymann', 'Marcellus Pittman'),
('Moodymann', 'Rick Wilhite')
;
create table allt(allf varchar(50));
insert into allt values('Moodymann | Theo Parrish | Rick Wade'),
('Jeff Mills | Moodymann | Rick Wilhite'),
('Jeff Mills | asdasdadasd | Rick Wilhite');
SELECT *
FROM allt
WHERE allt.allf LIKE '%Moodymann%'
| ALLF |
-----------------------------------------
| Moodymann | Theo Parrish | Rick Wade |
| Jeff Mills | Moodymann | Rick Wilhite |
我知道如何在子查询中使用REGEXP的唯一方法是使用该子查询生成REGEXP字符串
SELECT * FROM releases
WHERE
releases.all_artists REGEXP 'Moodymann'
OR releases.label_no_country='KDJ'
OR releases.all_artists REGEXP (
SELECT GROUP_CONCAT(similar_artist SEPARATOR '|')
FROM similar
WHERE artist='Moodymann'
GROUP BY similar_artist)
ORDER BY date DESC
以上内容没有经过测试,只是我可能尝试的一个理论。然而,这不会是非常理想的
更新
此后,我们对此进行了测试,发现类似艺术家的分组应该是艺术家的分组
SELECT * FROM releases
WHERE
releases.all_artists REGEXP 'Moodymann'
OR releases.label_no_country='KDJ'
OR releases.all_artists REGEXP (
SELECT GROUP_CONCAT(similar_artist SEPARATOR '|')
FROM similar
WHERE artist='Moodymann'
GROUP BY artist)
ORDER BY date DESC
然而,正如Pheonix所提到的,您最好重构您的结构,以拥有一个
releases\u artist
表。然后,您可以通过连接来完成所有这些工作,这会快得多。我知道如何在子查询中使用REGEXP的唯一方法是使用该子查询生成REGEXP字符串
SELECT * FROM releases
WHERE
releases.all_artists REGEXP 'Moodymann'
OR releases.label_no_country='KDJ'
OR releases.all_artists REGEXP (
SELECT GROUP_CONCAT(similar_artist SEPARATOR '|')
FROM similar
WHERE artist='Moodymann'
GROUP BY similar_artist)
ORDER BY date DESC
以上内容没有经过测试,只是我可能尝试的一个理论。然而,这不会是非常理想的
更新
此后,我们对此进行了测试,发现类似艺术家的分组应该是艺术家的分组
SELECT * FROM releases
WHERE
releases.all_artists REGEXP 'Moodymann'
OR releases.label_no_country='KDJ'
OR releases.all_artists REGEXP (
SELECT GROUP_CONCAT(similar_artist SEPARATOR '|')
FROM similar
WHERE artist='Moodymann'
GROUP BY artist)
ORDER BY date DESC
然而,正如Pheonix所提到的,您最好重构您的结构,以拥有一个
releases\u artist
表。然后,您可以通过连接来完成所有这些工作,这将要快得多。您可以在逗号分隔的列表上进行连接(不会快,但可能比在前导通配符中使用LIKE要快),并且您可以用逗号替换现有的分隔符来实现这一点。此外,您还可以使用大量的联合来让艺术家列表的行为类似于一个表来进行连接
此外,您还可以使用union而不是其他WHERE子句,这可能有助于允许使用索引(MySQL在一个查询中每个表只使用一个索引,因此在不同的列上使用或查询会强制MySQL不对正在检查的列之一使用索引)
因此,您可以执行以下操作:-
SELECT releases.*
FROM releases
INNER JOIN (SELECT 'Theo Parrish' AS anArtist UNION SELECT 'Jeff Mills' UNION SELECT 'Marcellus Pittman' UNION SELECT 'Rick Wilhite') Sub1
ON FIND_IN_SET(Sub1.anArtist, REPLACE(releases.all_artists, " | ", ",")) > 0
UNION
SELECT releases.*
FROM releases
WHERE releases.label_no_country='KDJ'
但是,如果更改数据库设计以将管道分隔的艺术家列表拆分到另一个表上是一个很小的选择,那么就改为这样做。它将更快,并将处理更多的艺术家。您可以在逗号分隔的列表上进行连接(不会很快,但可能比在前导通配符中使用LIKE更快),并且您可以用逗号替换现有的分隔符以允许此操作。此外,您还可以使用大量的联合来让艺术家列表的行为类似于一个表来进行连接 此外,您还可以使用union而不是其他WHERE子句,这可能有助于允许使用索引(MySQL在一个查询中每个表只使用一个索引,因此在不同的列上使用或查询会强制MySQL不对正在检查的列之一使用索引) 因此,您可以执行以下操作:-
SELECT releases.*
FROM releases
INNER JOIN (SELECT 'Theo Parrish' AS anArtist UNION SELECT 'Jeff Mills' UNION SELECT 'Marcellus Pittman' UNION SELECT 'Rick Wilhite') Sub1
ON FIND_IN_SET(Sub1.anArtist, REPLACE(releases.all_artists, " | ", ",")) > 0
UNION
SELECT releases.*
FROM releases
WHERE releases.label_no_country='KDJ'
但是,如果更改数据库设计以将管道分隔的艺术家列表拆分到另一个表上是一个很小的选择,那么就改为这样做。这将更快,并能应付更多的艺术家。我想你不需要第三个条件,因为第一个条件已经满足了。因此,我建议删除发行版。中的所有艺术家(从类似的位置选择类似的艺术家,其中的艺术家='Moodymann')我想在类似的艺术家中使用,因此使用子查询:)那么您想比较类似的内容吗?Moodymann | Theo Parrish | Rick Wade IN('Theo Parrish,Jeff Mills,Marcellus Pittman,Rick Wilhite')??对所有艺术家的查询都不会使用索引,而且可能会非常缓慢。最好将其拆分到一个包含多行的单独表中,然后您可以进行简单的连接。您必须重构(规范化)您的模式。试图将艺术家列表存储在一个列中只是自找麻烦。我认为你不需要第三个条件,因为第一个条件已经满足了。因此,我建议删除发行版。中的所有艺术家(从类似的位置选择类似的艺术家,其中的艺术家='Moodymann')我想在类似的艺术家中使用,因此使用子查询:)那么您想比较类似的内容吗?Moodymann | Theo Parrish | Rick Wade IN('Theo Parrish,Jeff Mills,Marcellus Pittman,Rick Wilhite')??对所有艺术家的查询都不会使用索引,而且可能会非常缓慢。最好将其拆分到一个包含多行的单独表中,然后您可以进行简单的连接。您必须重构(规范化)您的模式。试图将艺术家列表存储在一列中只会带来长期麻烦。我想在类似的艺术家中使用,因此使用子查询:)@Franco:在这种情况下,您需要规范化您的数据库。我想在类似的艺术家中使用,因此使用子查询:)@Franco:在这种情况下,您需要规范化您的数据库。