我有一个表格“位置”,结构如下:
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是beach(value - 1),mountain(value - 2)。
amenity_type是car(value - 1),bike(value - 2),football(value - 3)。
property_type是villa(value - 2),house(value - 3)
你能不能帮我获取SQL查询,选择property_id = location AND type_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1即属性有海滩和山脉,汽车,别墅和房子
这只是我的属性搜索应用程序中的过滤器示例。这可以有n种组合。请分享一个共同的逻辑,它将加入所有这些表并进行优化,以搜索大约一百万条记录。
我还需要计算所有条件。请分享相同的查询。
[编辑计数]:
假设我得到(property_id,其中location_type = 1 AND property_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1)为1500.我需要获得具有相同条件的计数和其他property_type,location_type, amenity_type。
例如:
1)(property_id,其中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,其中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与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与location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1)和amenity_type = 3
等等。它给我带来了很大的开销。请帮忙。另请注意,location_types,amenity_type,property_type是动态的,即用户可以在主表中添加更多location_type,我需要获取更多location_types的计数。
答案 0 :(得分:4)
在这种情况下,如果您有多个值,那么多个表没有任何问题。你在这里做的很好。这是您需要的查询:
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
一旦你知道如何写就很容易:
你也可以明确地使用“join”,但我发现上面的方法比较简单,对db引擎来说无关紧要。
[从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列上声明索引,也在您拥有的不同类型列上声明索引。这很关键。但是一旦你有了这个,只有几百万行,这应该很快 - 上面是不一个非常复杂的查询,你有少于一GB的数据(考虑使用tinyint作为类型列)。别担心......别名(“作为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和每行的计数(因此您可以在上面执行上面提到的所有查询)。
答案 1 :(得分:1)
select property_id from (
select property_id
from location
where location_type in (1,2)
group by property_id
having count(location_type) = 2
union all
select property_id
from amenities
where amenity_type = 1
group by property_id
union all
select property_id
from property
where property_type in (1,3)
group by property_id
having count(property_type) = 2
) as t
group by property_id
having count(property_id) = 3
遵循我之前回答的相同逻辑,您可以使用union all来查找满足每个条件的property_id。在这种情况下,有3个查询。因此,您可以对此属性进行分组,如果计数等于3,则表示property_id满足所有条件。如果不满足单个标准,则不会返回property_id。
修改强>
另一种可能的解决方案:
select property_id
from location
where location_type in (1,2)
group by property_id
having count(location_type) = 2
and property_id in (
select property_id
from amenities
where amenity_type = 1
group by property_id )
and property_id in (
select property_id
from property
where property_type in (1,3)
group by property_id
having count(property_type) = 2
)
它也适用于您的几个示例记录,但我确信在大型数据集上,此查询的性能会非常差。 ;)
答案 2 :(得分:0)
如果您需要执行该查询,最重要的部分是确保所有各个字段都具有索引。但是,由于每个表中的每个条目与其他表中的条目具有一对一的关系,因此最好只使用一个表。