我有一个表“位置”,其结构为:
id | property_id | location_type
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 3 | 2
5 | 4 | 1
6 | 4 | 2
我有另一个表“便利设施”,其结构为:
id | property_id | amenity_type
1 | 1 | 1
2 | 1 | 3
3 | 2 | 2
4 | 3 | 4
5 | 4 | 1
6 | 4 | 3
我有另一个表“属性”,其结构为:
id | property_id | property_type
1 | 1 | 2
2 | 1 | 3
3 | 2 | 2
4 | 3 | 4
5 | 4 | 2
6 | 4 | 3
id - 是相应表的主键。 property_id 是我的数据库的属性 ID(外键)。 location_type 是海滩(值 - 1)、山(值 - 2)。
amenity_type 是汽车(值 - 1)、自行车(值 - 2)、足球(值 - 3)。
property_type 是别墅(值 - 2)、别墅(值 - 3)
您能否帮助我获取 SQL 查询来选择具有 location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1 的 property_id,即特性有海滩、山脉、汽车、别墅和房屋.
这只是我的属性搜索应用程序中的过滤器示例。对此可以有n种组合。请分享一个通用逻辑,该逻辑将连接所有这些表并进行优化以搜索大约一百万条记录。
我还需要计算所有条件。请分享同样的查询。
[编辑计数]:
假设我得到的 (property_id with location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1) 的计数为 1500。我需要获取具有相同条件和其他 property_type、location_type 的计数,设施类型。
例如:
1) (property_id with location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1) AND location_type = 3 的计数
2) (property_id with location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1) AND location_type = 4 的计数
3) (property_id with location_type = 1 AND location_type = 2 AND amenity_type = 1 的计数 AND property_type = 3 AND property_type = 1) AND amenity_type = 2
4) (property_id with location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1) AND amenity_type = 3 的计数
等等。这对我来说是一笔很大的开销。请帮忙。另外,请注意,location_types、amenity_type、property_type 是动态的,即用户可以在主表中添加更多 location_type,而我需要获取更多 location_type 的计数。
最佳答案
在像这样有多个值的情况下,多个表没有任何问题。你在这里做的事情很好。这是您需要的查询:
select distinct l1.property_id
from location as l1, location as l2,
amentities as a,
properties as p1, properties as p2
where l1.property_id = l2.property_id
and l1.property_id = a.property_id
and l1.property_id = p1.property_id
and l1.property_id = p2.property_id
and l1.location_type = 1
and l2.location_type = 2
and a.amenity_type = 1
and p1.property_type = 3
and p2.property_type = 1
一旦你明白了如何写就很容易了:
- 为您需要的每个表/条件组合创建一个别名
- 确保所有属性同时处理相同的 property_id (l1.property_id = ...)
- 然后指定每个表/条件的条件
您也可以显式使用“join”,但我发现上面的方法更简单,并且对数据库引擎来说应该不重要。
[从 ypercube 编辑显示 JOIN 语法]:
SELECT p.id
FROM
property AS p
JOIN
location AS l1
ON l1.property_id = p.id
AND l1.location_type = 1
JOIN
location AS l2
ON l2.property_id = p.id
AND l2.location_type = 2
JOIN
amentities AS a1
ON a1.property_id = p.id
AND a1.amenity_type = 2
JOIN
properties AS p1
ON p1.property_id = p.id
AND p1.property_type = 3
JOIN
properties AS p2
ON p2.property_id = p.id
AND p2.property_type = 1
[来自 ac 的评论:这和初始语法应该在内部翻译成相同的查询,因此两者同样有效]
[关于性能的编辑]一般来说,为了获得良好的数据库性能,您唯一需要担心的(或者至少是迄今为止最重要的)事情是索引。您想要在每个表的 property_id 列以及您拥有的不同类型列上声明一个索引。这很关键。但是一旦你有了这个,对于只有几百万行,这应该很快 - 上面的不是一个非常复杂的查询,并且你的数据少于 1GB(考虑使用tinyint作为类型列)。别担心...别名(“as X”)根本不是问题。
[编辑计数] 对于 count of (property_id with location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1) AND location_type = X
您想要类似以下内容:
select lx.location_id, count(l1.property_id)
from location as l1, location as l2, location as lx
amentities as a,
properties as p1, properties as p2
where l1.property_id = l2.property_id
and l1.property_id = a.property_id
and l1.property_id = p1.property_id
and l1.property_id = p2.property_id
and l1.property_id = lx.property_id
and l1.location_type = 1
and l2.location_type = 2
and a.amenity_type = 1
and p1.property_type = 3
and p2.property_type = 1
group by lx.location_type
但我还没有测试过它或任何东西。这应该会为您提供多行,其中包含每一行的 location_type 和计数(因此您可以在一个查询中执行上面给出的所有查询)。
关于MySQL查询-复杂搜索条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7053627/