我有一个相当复杂的查询,它在4个表中搜索一个或多个关键字:
select distinct textures.id from textures
left join `category_texture` on `category_texture`.`texture_id` = `textures`.`id`
left join `categories` on `categories`.`id` = `category_texture`.`category_id`
left join `tag_texture` on `tag_texture`.`texture_id` = `textures`.`id`
left join `tags` on `tags`.`id` = `tag_texture`.`tag_id`
left join `size_texture` on `size_texture`.`texture_id` = `textures`.`id`
left join `sizes` on `sizes`.`id` = `size_texture`.`size_id`
WHERE ( (textures.name LIKE '%artwork%'
OR categories.name LIKE '%artwork%'
OR tags.name LIKE '%artwork%'
OR sizes.name LIKE '%artwork%') AND (textures.name LIKE '%super%'
OR categories.name LIKE '%super%'
OR tags.name LIKE '%super%'
OR sizes.name LIKE '%super%') AND (textures.name LIKE '%master%'
OR categories.name LIKE '%master%'
OR tags.name LIKE '%master%'
OR sizes.name LIKE '%master%') ) AND `textures`.`is_published` = 1 group by `tags`.`name`, `categories`.`name`, `sizes`.`name`, `textures`.`id`
在此示例中,图稿是一个类别,master和super是标签。问题是如果我重复任何表,都没有找到结果:
提前致谢。
为清晰起见编辑:
我的目标是能够在这些表中搜索数据,这样我就可以组合同一个表的多个实例。例如,如果我搜索“艺术品超级大师”,它应该返回我的所有纹理与“艺术品”类别(因为它是唯一找到该单词的地方)和标签“超级”和“主人”(两者都是)。
目前使用此查询我可以从任何这些表中进行搜索,但前提是我的搜索在同一个表中找不到2件以上的内容。因此,搜索类别+纹理名称+标记+大小有效,但搜索找到2个标记的内容失败。
答案 0 :(得分:1)
您的查询尝试执行的操作有两个问题。首先,参数的数量可以变化,这需要针对每个变体使用不同的查询语法(或者一些丑陋的黑客来解决它)。其次,对于每个表,只想返回与中的一个参数匹配的行,除非在您想要返回所有行时没有匹配。
也许这对你有用:
select distinct textures.id
from textures
join category_texture on category_texture.texture_id = textures.id
join categories on categories.id = category_texture.category_id
join tag_texture on tag_texture.texture_id = textures.id
join tags on tags.id = tag_texture.tag_id
left join size_texture on size_texture.texture_id = textures.id
join sizes on sizes.id = size_texture.size_id
WHERE ((textures.name LIKE '%artwork%' OR textures.name LIKE '%super%' OR textures.name LIKE '%master%')
OR (0 = select count(*) from textures where (textures.name LIKE '%artwork%' OR textures.name LIKE '%super%' OR textures.name LIKE '%master%') ) )
AND ((categories.name LIKE '%artwork%' OR categories.name LIKE '%super%' OR categories.name LIKE '%master%')
OR (0 = select count(*) from categories where (categories.name LIKE '%artwork%' OR categories.name LIKE '%super%' OR categories.name LIKE '%master%') ) )
AND ((tags.name LIKE '%artwork%' OR tags.name LIKE '%super%' OR tags.name LIKE '%master%')
OR (0 = select count(*) from tags where (tags.name LIKE '%artwork%' OR tags.name LIKE '%super%' OR tags.name LIKE '%master%') ) )
AND ((sizes.name LIKE '%artwork%' OR sizes.name LIKE '%super%' OR sizes.name LIKE '%master%')
OR (0 = select count(*) from name where (sizes.name LIKE '%artwork%' OR sizes.name LIKE '%super%' OR sizes.name LIKE '%master%') ) )
AND textures.is_published = 1
group by textures.id, tags.name, categories.name, sizes.name, textures.name
编辑由于您的代码动态生成SQL,我已经放入了原始示例中的值。
这整个查询非常难看,但它应该有效。 如果您需要执行此类搜索,则需要重新考虑数据结构。
答案 1 :(得分:1)
我有一个反思,也许这种方法更好:
SELECT T1.id
FROM
(
select textures.id
from textures
WHERE textures.name LIKE '%texture1%'
UNION
select textures.id
from textures
join category_texture on category_texture.texture_id = textures.id
join categories on categories.id = category_texture.category_id
WHERE categories.name LIKE '%texture1%'
UNION
select textures.id
from textures
join tag_texture on tag_texture.texture_id = textures.id
join tags on tags.id = tag_texture.tag_id
WHERE tags.name LIKE '%texture1%'
UNION
select textures.id
from textures
join size_texture on size_texture.texture_id = textures.id
join sizes on sizes.id = size_texture.size_id
WHERE sizes.name LIKE '%texture1%'
) AS T1
JOIN
(
select textures.id
from textures
WHERE textures.name LIKE '%category2%'
UNION
select textures.id
from textures
join category_texture on category_texture.texture_id = textures.id
join categories on categories.id = category_texture.category_id
WHERE categories.name LIKE '%category2%'
UNION
select textures.id
from textures
join tag_texture on tag_texture.texture_id = textures.id
join tags on tags.id = tag_texture.tag_id
WHERE tags.name LIKE '%category2%'
UNION
select textures.id
from textures
join size_texture on size_texture.texture_id = textures.id
join sizes on sizes.id = size_texture.size_id
WHERE sizes.name LIKE '%category2%'
) AS T2
ON T1.id = T2.id
JOIN
(
select textures.id
from textures
WHERE textures.name LIKE '%tag3%'
UNION
select textures.id
from textures
join category_texture on category_texture.texture_id = textures.id
join categories on categories.id = category_texture.category_id
WHERE categories.name LIKE '%tag3%'
UNION
select textures.id
from textures
join tag_texture on tag_texture.texture_id = textures.id
join tags on tags.id = tag_texture.tag_id
WHERE tags.name LIKE '%tag3%'
UNION
select textures.id
from textures
join size_texture on size_texture.texture_id = textures.id
join sizes on sizes.id = size_texture.size_id
WHERE sizes.name LIKE '%tag3%'
) AS T3
ON T1.id = T3.id
只需添加更多/更少的JOIN...ON T1.id = Tn.id
部分以匹配您的参数。
这是表示执行的小提琴:http://sqlfiddle.com/#!9/9abe6/1